diff --git a/README.md b/README.md index bae9b4c0..834ac314 100644 --- a/README.md +++ b/README.md @@ -29,15 +29,22 @@ Lemonade and vLLM. | Platform | Prebuilt binary | Notes | |---|---|---| -| Linux (x86_64) | Yes | Full support, including the live dashboard and both inference engines | +| Linux (x86_64) | Yes | Ubuntu 24.04 or newer; full support, including the live dashboard and both inference engines | | Windows (x86_64) | Yes | CLI and Lemonade serving; no live dashboard or vLLM | -| WSL2 (x86_64) | Yes (Linux binary) | Full support, including the live dashboard; see [docs/wsl.md](docs/wsl.md) for setup | +| WSL2 (x86_64) | Yes (Linux binary) | Ubuntu 24.04 or newer; full support, including the live dashboard; see [docs/wsl.md](docs/wsl.md) for setup | | macOS | No | No official installer, release, CI, or QA coverage | Live dashboard telemetry requires Linux or WSL2 (see [Interactive interfaces](#interactive-interfaces)). vLLM serving is Linux/WSL2 only (see [docs/vllm.md](docs/vllm.md)). +The minimum supported Linux release, native or under WSL2, is Ubuntu 24.04. On +other distributions the equivalent requirement is glibc 2.38 with +`GLIBCXX_3.4.32`: that is what the Lemonade engine is linked against, and every +published build of it needs those versions, so there is no older release to fall +back to. Ubuntu 22.04 ships glibc 2.35 and cannot run it; Ubuntu 24.04 provides +glibc 2.39 and `GLIBCXX_3.4.33`. + > [!IMPORTANT] > **Tech Preview** -- This software is provided as-is, without warranty or > guarantee of stability. APIs, commands, and behavior may change without diff --git a/docs/wsl.md b/docs/wsl.md index 1b9a90a1..24a53679 100644 --- a/docs/wsl.md +++ b/docs/wsl.md @@ -14,7 +14,10 @@ virtual environments and ROCDXG (`librocdxg`). The AMD WSL path is: 1. Windows 11 with the AMD Adrenalin WSL-capable driver. -2. WSL2 with Ubuntu 24.04 or Ubuntu 22.04. +2. WSL2 with Ubuntu 24.04 or newer. Ubuntu 22.04 is not supported: it ships + glibc 2.35, below the glibc 2.38 / `GLIBCXX_3.4.32` floor that every + published Lemonade embeddable requires, so the Lemonade engine cannot start + there. Ubuntu 24.04 provides glibc 2.39 and `GLIBCXX_3.4.33`. 3. ROCDXG (`librocdxg`) installed inside WSL. 4. A TheRock runtime installed by `rocm-cli` into a managed Python venv. diff --git a/scripts/wsl_preflight.py b/scripts/wsl_preflight.py index 436b0db2..042aab4e 100644 --- a/scripts/wsl_preflight.py +++ b/scripts/wsl_preflight.py @@ -258,11 +258,20 @@ def evaluate( sdk_headers = state.get("windows_sdk_headers") or [] version_id = str(os_release.get("VERSION_ID") or "") - supported_ubuntu = os_release.get("ID") == "ubuntu" and version_id in { - "22.04", - "24.04", - "26.04", - } + # 22.04 is deliberately unsupported: its glibc 2.35 is below the glibc 2.38 / + # GLIBCXX_3.4.32 floor every published Lemonade embeddable is linked + # against, so the Lemonade engine cannot start on it. See docs/wsl.md. + version_parts = version_id.split(".") + ubuntu_version = None + if len(version_parts) == 2 and all( + part.isascii() and part.isdecimal() for part in version_parts + ): + ubuntu_version = (int(version_parts[0]), int(version_parts[1])) + supported_ubuntu = ( + os_release.get("ID") == "ubuntu" + and ubuntu_version is not None + and ubuntu_version >= (24, 4) + ) build_tools = all( tools.get(name) for name in ["git", "cmake", "gcc", "g++", "make"] ) @@ -270,7 +279,9 @@ def evaluate( checks = [ Check("wsl", bool(state.get("is_wsl")), "WSL marker or /dev/dxg detected"), Check( - "ubuntu", supported_ubuntu, f"Ubuntu VERSION_ID={version_id or ''}" + "ubuntu", + supported_ubuntu, + f"Ubuntu 24.04 or newer (VERSION_ID={version_id or ''})", ), Check("dxg_device", bool(paths.get("/dev/dxg")), "/dev/dxg"), Check( @@ -391,6 +402,28 @@ def self_test() -> None: checks = evaluate(ready_state, require_rocm_tools=False) assert all(check.ok for check in checks if check.required), checks + for version_id in ["24.04", "24.10", "25.04", "26.04", "28.04"]: + supported_state = json.loads(json.dumps(ready_state)) + supported_state["os_release"]["VERSION_ID"] = version_id + checks = evaluate(supported_state, require_rocm_tools=False) + assert any(check.name == "ubuntu" and check.ok for check in checks), checks + assert all(check.ok for check in checks if check.required), checks + + # 22.04 is below the Lemonade glibc floor, and malformed or unknown + # versions must fail closed rather than report an otherwise perfect host ready. + for version_id in ["22.04", "24.04.1", "unknown", ""]: + unsupported_state = json.loads(json.dumps(ready_state)) + unsupported_state["os_release"]["VERSION_ID"] = version_id + checks = evaluate(unsupported_state, require_rocm_tools=False) + assert any(check.name == "ubuntu" and not check.ok for check in checks), checks + assert not all(check.ok for check in checks if check.required), checks + + missing_version_state = json.loads(json.dumps(ready_state)) + del missing_version_state["os_release"]["VERSION_ID"] + checks = evaluate(missing_version_state, require_rocm_tools=False) + assert any(check.name == "ubuntu" and not check.ok for check in checks), checks + assert not all(check.ok for check in checks if check.required), checks + def main() -> int: parser = argparse.ArgumentParser(description=__doc__)