mirror of
https://github.com/lutris/lutris.git
synced 2026-07-30 15:15:56 -04:00
Three related bugs prevented the AppImage's WebKit-based service login from working on Fedora / Arch / openSUSE — invisible on Ubuntu because the host happens to satisfy the AppDir's missing pieces. 1. TLS backend not bundled. linuxdeploy-plugin-gtk copies libgio but not the GIO modules directory that holds glib-networking's libgiognutls.so. Without it GIO falls back to a compile-time libdir that doesn't exist off-Debian, and WebKit reports "TLS is not available" on the first HTTPS request. Copy the modules directory into $APPDIR/usr/lib/gio/modules with an $ORIGIN/../.. RPATH, add glib-networking to apt explicitly (it was pulled transitively but its modules weren't being copied), and export GIO_MODULE_DIR in AppRun. 2. WebKit shared libraries not bundled. libwebkit2gtk-4.1 and libjavascriptcoregtk-4.1 are loaded lazily via gi.repository when the user clicks a login button, so they never appear in any binary's NEEDED chain — linuxdeploy has no reason to bundle them. On non-Ubuntu hosts dlopen() falls through to the host copies with different symbols, e.g. `undefined symbol: webkit_web_context_new`. Pass both sonames to linuxdeploy explicitly. 3. WebKit helper processes not bundled and hardcoded path unreachable. WebKit2 4.1 forks WebKitNetworkProcess / WebKitWebProcess from a compile-time path baked into libwebkit2gtk-4.1.so.0 (/usr/lib/x86_64-linux-gnu/webkit2gtk-4.1/). linuxdeploy bundles shared libraries, not auxiliary executables, and WEBKIT_EXEC_PATH was removed upstream — the path is only overridable by byte-patching the .so. Copy the webkit2gtk-4.1/ directory into the AppDir with $ORIGIN/.. RPATH on each helper, and byte-patch the hardcoded compile-time path inside libwebkit2gtk-4.1.so.0 to a writable /tmp/.lutris-appimage.dir/webkit2gtk-4.1 (same byte length). AppRun creates the symlink there before launch. Also disable WebKit's bubblewrap sandbox (WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1): bwrap opens a fresh mount namespace that can't see the AppImage's FUSE mount at /tmp/.mount_LutrisXXX, so any helper spawned inside it fails to reach either the symlink target or the bundled libs. Lutris already runs unsandboxed and spawns Wine, so an additional WebKit sandbox buys negligible isolation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
102 lines
4.6 KiB
Bash
Executable File
102 lines
4.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# AppRun entry point for the Lutris AppImage.
|
|
#
|
|
# Two responsibilities:
|
|
# 1. Source linuxdeploy-plugin-gtk's hook so GI_TYPELIB_PATH, GDK_PIXBUF_*,
|
|
# XDG_DATA_DIRS, etc. point inside the AppDir.
|
|
# 2. Launch bin/lutris with the bundled Python interpreter.
|
|
#
|
|
# Lutris is intentionally NOT sandboxed: it must call host binaries (xrandr,
|
|
# 7z, fuser, wine, the user's installed runners), read the user's $HOME,
|
|
# and access mounted drives. We deliberately leave PATH and PYTHONPATH
|
|
# alone so host tools and host Python (used by host subprocesses like
|
|
# umu-run) work as they do outside the AppImage. The build script
|
|
# installs Lutris's package files via --install-layout=deb so the
|
|
# bundled Python finds them via its standard dist-packages search,
|
|
# without us needing to advertise an AppDir path on PYTHONPATH.
|
|
set -e
|
|
|
|
HERE="$(dirname "$(readlink -f "${0}")")"
|
|
|
|
# linuxdeploy-plugin-gtk writes its environment setup into apprun-hooks/.
|
|
# Source every hook it dropped so we inherit the GTK/Pixbuf/typelib paths.
|
|
if [ -d "$HERE/apprun-hooks" ]; then
|
|
for hook in "$HERE"/apprun-hooks/*.sh; do
|
|
# shellcheck disable=SC1090
|
|
[ -r "$hook" ] && . "$hook"
|
|
done
|
|
fi
|
|
|
|
export APPDIR="$HERE"
|
|
|
|
# WebKit2 4.1 spawns helper processes (WebKitNetworkProcess,
|
|
# WebKitWebProcess) from a compile-time path baked into
|
|
# libwebkit2gtk-4.1.so.0. WEBKIT_EXEC_PATH does not exist in this
|
|
# build, so the build script byte-patched the hardcoded path inside
|
|
# the .so to /tmp/.lutris-appimage.dir/webkit2gtk-4.1 (same length as
|
|
# the original). Symlink that location to our bundled helpers before
|
|
# launching.
|
|
#
|
|
# Disable WebKit's bubblewrap sandbox: it creates a fresh mount
|
|
# namespace with only paths WebKit's own policy bind-mounts, and the
|
|
# AppImage's FUSE mount at /tmp/.mount_LutrisXXX is not one of them.
|
|
# The helpers execvp inside the sandbox and can't reach either the
|
|
# symlink target or the bundled libs. Lutris already runs with full
|
|
# user-home access and spawns Wine binaries — a WebKit sandbox layered
|
|
# on top adds negligible additional isolation, and disabling it is
|
|
# standard practice for AppImage-packaged WebKitGTK apps.
|
|
if [ -d "$HERE/usr/lib/webkit2gtk-4.1" ]; then
|
|
mkdir -p /tmp/.lutris-appimage.dir
|
|
ln -snf "$HERE/usr/lib/webkit2gtk-4.1" /tmp/.lutris-appimage.dir/webkit2gtk-4.1
|
|
export WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1
|
|
fi
|
|
|
|
# GLib's GIO looks for extension modules (TLS backends, proxy resolvers,
|
|
# etc.) at a compile-time libdir. Point it at our bundled copy explicitly;
|
|
# otherwise WebKit reports "TLS is not available" and any HTTPS login flow
|
|
# fails at the first request. This is silently masked on Debian/Ubuntu
|
|
# hosts because the compile-time fallback path exists there, but breaks
|
|
# on Fedora/Arch/openSUSE where it doesn't.
|
|
if [ -d "$HERE/usr/lib/gio/modules" ]; then
|
|
export GIO_MODULE_DIR="$HERE/usr/lib/gio/modules"
|
|
fi
|
|
|
|
# Intentionally do NOT export LD_LIBRARY_PATH. linuxdeploy already set
|
|
# RPATH=$ORIGIN/.. on every bundled binary, so they find their sibling libs
|
|
# without an env override. Exporting LD_LIBRARY_PATH here would leak into
|
|
# subprocesses — and Lutris launches host binaries constantly (xrandr, 7z,
|
|
# fuser, /usr/bin/flatpak, wine, etc.). Forcing them to load our older
|
|
# bundled libssl/libcrypto/libstdc++ breaks any host tool whose own deps
|
|
# were built against newer symbols. The cost of this discipline is that
|
|
# anything we copied into the AppDir manually (PyGObject's _gi.so,
|
|
# python3-dbus' bindings) must have its RPATH patched by the build script,
|
|
# since linuxdeploy only patches files it deploys itself.
|
|
unset LD_LIBRARY_PATH
|
|
|
|
# Python: find the bundled interpreter and site-packages. We accept any
|
|
# python3.X under usr/bin so this script doesn't need to be rev'd when the
|
|
# build image's Python minor version changes.
|
|
PYTHON_BIN=""
|
|
for cand in "$HERE"/usr/bin/python3.* "$HERE"/usr/bin/python3; do
|
|
if [ -x "$cand" ] && [ ! -L "$cand" ]; then
|
|
PYTHON_BIN="$cand"
|
|
break
|
|
fi
|
|
done
|
|
if [ -z "$PYTHON_BIN" ]; then
|
|
# Fallback: host python3. The AppImage is less portable this way, but
|
|
# at least it boots so the user sees a real error rather than nothing.
|
|
PYTHON_BIN="$(command -v python3 || true)"
|
|
fi
|
|
if [ -z "$PYTHON_BIN" ]; then
|
|
echo "Lutris AppImage: no python3 interpreter found in AppDir or host" >&2
|
|
exit 1
|
|
fi
|
|
|
|
# bin/lutris strips /home paths from sys.path unless this is set, which
|
|
# would also drop the AppDir paths Python auto-discovered when extracted
|
|
# AppImages live under /home (e.g. ~/Applications).
|
|
export LUTRIS_ALLOW_LOCAL_PYTHON_PACKAGES=1
|
|
|
|
exec "$PYTHON_BIN" "$HERE/usr/bin/lutris" "$@"
|