Added better support for kubuntu and fixed some issues with telemetry.
This commit is contained in:
@@ -42,19 +42,71 @@ class DoctorReport:
|
||||
package_hint: str | None
|
||||
warnings: list[str]
|
||||
|
||||
@property
|
||||
def blockers(self) -> tuple[str, ...]:
|
||||
return host_readiness_blockers(self)
|
||||
|
||||
def to_dict(self) -> dict[str, object]:
|
||||
return asdict(self)
|
||||
payload = asdict(self)
|
||||
payload["blockers"] = list(self.blockers)
|
||||
return payload
|
||||
|
||||
|
||||
def inspect_host(environment: Mapping[str, str] | None = None) -> DoctorReport:
|
||||
def host_readiness_blockers(report: DoctorReport) -> tuple[str, ...]:
|
||||
"""Explain every condition that makes a host report fail readiness."""
|
||||
|
||||
blockers = [
|
||||
f"{tool.name} is missing ({tool.purpose})."
|
||||
for tool in report.tools
|
||||
if tool.required and tool.path is None
|
||||
]
|
||||
bubblewrap = next(
|
||||
(tool for tool in report.tools if tool.name == "bubblewrap"),
|
||||
None,
|
||||
)
|
||||
if (
|
||||
bubblewrap is not None
|
||||
and bubblewrap.required
|
||||
and bubblewrap.path is not None
|
||||
and not report.container_host.ready
|
||||
):
|
||||
issue = report.container_host.issue or "probe failed"
|
||||
message = f"Bubblewrap cannot create the Steam Runtime sandbox ({issue})."
|
||||
if report.container_host.recommendation:
|
||||
message += f" {report.container_host.recommendation}"
|
||||
blockers.append(message)
|
||||
if report.container_host.broken_umu_profile_link:
|
||||
blockers.append(
|
||||
"UMU's AppArmor profile link is broken; run "
|
||||
"`pristontale-eu container-host --repair`."
|
||||
)
|
||||
if not report.ok and not blockers:
|
||||
blockers.append(
|
||||
"The host readiness check failed for an unclassified reason; "
|
||||
"run `pristontale-eu --json doctor` and report its output."
|
||||
)
|
||||
return tuple(blockers)
|
||||
|
||||
|
||||
def inspect_host(
|
||||
environment: Mapping[str, str] | None = None,
|
||||
*,
|
||||
vulkan_support: Mapping[str, object] | None = None,
|
||||
) -> DoctorReport:
|
||||
env = os.environ if environment is None else environment
|
||||
os_release = _read_os_release()
|
||||
distribution = os_release.get("ID", "unknown")
|
||||
version = os_release.get("VERSION_ID", "unknown")
|
||||
architecture = platform.machine()
|
||||
wine_tools = find_wine_tools()
|
||||
umu_path = _umu_path(env)
|
||||
container_host = inspect_container_host(environment=env)
|
||||
container_required = umu_path is not None
|
||||
detected_vulkan = (
|
||||
dict(vulkan_support)
|
||||
if vulkan_support is not None
|
||||
else _inspect_vulkan_support(env)
|
||||
)
|
||||
tools = [
|
||||
ToolStatus(
|
||||
"python3",
|
||||
@@ -117,9 +169,11 @@ def inspect_host(environment: Mapping[str, str] | None = None) -> DoctorReport:
|
||||
"Vulkan diagnostics",
|
||||
),
|
||||
]
|
||||
tools.extend(_platform_optional_tools(distribution, architecture=platform.machine()))
|
||||
if architecture.casefold() in {"x86_64", "amd64"}:
|
||||
tools.extend(_vulkan_tool_statuses(detected_vulkan, distribution))
|
||||
tools.extend(_platform_optional_tools(distribution, architecture=architecture))
|
||||
warnings: list[str] = []
|
||||
if platform.machine().casefold() not in {"x86_64", "amd64"}:
|
||||
if architecture.casefold() not in {"x86_64", "amd64"}:
|
||||
warnings.append("PristonTale EU requires an x86-64 host with 32-bit Vulkan support.")
|
||||
if not env.get("WAYLAND_DISPLAY") and not env.get("DISPLAY"):
|
||||
warnings.append("No graphical X11 or Wayland session is visible.")
|
||||
@@ -138,7 +192,7 @@ def inspect_host(environment: Mapping[str, str] | None = None) -> DoctorReport:
|
||||
"UMU's AppArmor profile link is broken and may prevent profiles from "
|
||||
"loading after reboot; run `pristontale-eu container-host --repair`."
|
||||
)
|
||||
warnings.extend(_arch_runtime_warnings(distribution, platform.machine()))
|
||||
warnings.extend(_arch_runtime_warnings(distribution, architecture))
|
||||
required_ok = all(item.path is not None for item in tools if item.required)
|
||||
return DoctorReport(
|
||||
ok=(
|
||||
@@ -148,7 +202,7 @@ def inspect_host(environment: Mapping[str, str] | None = None) -> DoctorReport:
|
||||
),
|
||||
distribution=distribution,
|
||||
version=version,
|
||||
architecture=platform.machine(),
|
||||
architecture=architecture,
|
||||
display_backend="wayland" if env.get("WAYLAND_DISPLAY") else "x11",
|
||||
tools=tools,
|
||||
container_host=container_host,
|
||||
@@ -228,11 +282,6 @@ def _platform_optional_tools(distribution: str, *, architecture: str) -> list[To
|
||||
return []
|
||||
if distribution in ARCH_FAMILY_DISTRIBUTIONS:
|
||||
return [
|
||||
_optional_tool_status(
|
||||
"lib32-vulkan",
|
||||
"/usr/lib32/libvulkan.so.1",
|
||||
"32-bit Vulkan runtime compatibility layer",
|
||||
),
|
||||
_optional_tool_status(
|
||||
"lib32-gstreamer",
|
||||
"/usr/lib32/gstreamer-1.0",
|
||||
@@ -250,11 +299,6 @@ def _arch_runtime_warnings(distribution: str, architecture: str) -> list[str]:
|
||||
"Non-x86_64 Linux hosts are not a supported runtime architecture for this game."
|
||||
]
|
||||
warnings: list[str] = []
|
||||
if not _path_exists("/usr/lib32/libvulkan.so.1"):
|
||||
warnings.append(
|
||||
"Install lib32-vulkan-icd-loader and the GPU vendor's matching 32-bit "
|
||||
"Vulkan driver; this 32-bit D3D9 client otherwise cannot initialize DXVK."
|
||||
)
|
||||
if not _path_exists("/usr/lib32/gstreamer-1.0"):
|
||||
warnings.append(
|
||||
"Install lib32-gstreamer and lib32-gst-plugins-base if the login video or "
|
||||
@@ -264,6 +308,77 @@ def _arch_runtime_warnings(distribution: str, architecture: str) -> list[str]:
|
||||
return warnings
|
||||
|
||||
|
||||
def _inspect_vulkan_support(environment: Mapping[str, str]) -> dict[str, object]:
|
||||
try:
|
||||
from .telemetry_environment import inspect_vulkan_support
|
||||
|
||||
return inspect_vulkan_support(environment)
|
||||
except Exception:
|
||||
return {}
|
||||
|
||||
|
||||
def _vulkan_tool_statuses(
|
||||
support: Mapping[str, object],
|
||||
distribution: str,
|
||||
) -> list[ToolStatus]:
|
||||
return [
|
||||
_vulkan_tool_status(64, support, distribution),
|
||||
_vulkan_tool_status(32, support, distribution),
|
||||
]
|
||||
|
||||
|
||||
def _vulkan_tool_status(
|
||||
bits: int,
|
||||
support: Mapping[str, object],
|
||||
distribution: str,
|
||||
) -> ToolStatus:
|
||||
available = support.get(f"vulkan_{bits}bit") is True
|
||||
loader_available = support.get(f"vulkan_{bits}bit_loader_available") is True
|
||||
icd_available = support.get(f"vulkan_{bits}bit_icd_available") is True
|
||||
purpose = f"{bits}-bit Vulkan loader and GPU ICD required by DXVK"
|
||||
if not available:
|
||||
missing_parts: list[str] = []
|
||||
if not loader_available:
|
||||
missing_parts.append("loader")
|
||||
if not icd_available:
|
||||
missing_parts.append("GPU driver/ICD")
|
||||
purpose = (
|
||||
f"{bits}-bit Vulkan {' and '.join(missing_parts)} required by DXVK; "
|
||||
+ _vulkan_package_guidance(distribution, bits)
|
||||
)
|
||||
return ToolStatus(
|
||||
f"vulkan-{bits}bit",
|
||||
"loader+ICD" if available else None,
|
||||
True,
|
||||
purpose,
|
||||
)
|
||||
|
||||
|
||||
def _vulkan_package_guidance(distribution: str, bits: int) -> str:
|
||||
suffix = ":i386" if bits == 32 else ""
|
||||
if distribution == "ubuntu":
|
||||
return (
|
||||
"on Ubuntu/Kubuntu install "
|
||||
f"libvulkan1{suffix} and the matching GPU package "
|
||||
f"(mesa-vulkan-drivers{suffix} or libnvidia-gl-<version>{suffix})"
|
||||
)
|
||||
if distribution in {"debian", "linuxmint", "pop", "elementary", "zorin"}:
|
||||
return (
|
||||
f"with APT install libvulkan1{suffix} and the matching {bits}-bit GPU ICD"
|
||||
)
|
||||
if distribution in {"fedora", "nobara"}:
|
||||
return f"install the matching {bits}-bit Vulkan loader and GPU driver with DNF"
|
||||
if distribution in ARCH_FAMILY_DISTRIBUTIONS:
|
||||
return (
|
||||
"install vulkan-icd-loader and the GPU vendor driver"
|
||||
if bits == 64
|
||||
else "install lib32-vulkan-icd-loader and the matching lib32 GPU driver"
|
||||
)
|
||||
if distribution in {"opensuse-tumbleweed", "opensuse-leap", "suse"}:
|
||||
return f"install the matching {bits}-bit Vulkan loader and GPU driver with Zypper"
|
||||
return f"install the matching {bits}-bit Vulkan loader and GPU driver"
|
||||
|
||||
|
||||
def _optional_tool_status(name: str, path: str, purpose: str) -> ToolStatus:
|
||||
if _path_exists(path):
|
||||
return ToolStatus(name, path, required=False, purpose=purpose)
|
||||
|
||||
Reference in New Issue
Block a user