feat: Controller support, performance enchancements, multi-stage images, fixes (#304)

## Description
Oops.. another massive PR 🥲 

This PR contains multiple improvements and changes.

Firstly, thanks gst-wayland-display's PR
[here](https://github.com/games-on-whales/gst-wayland-display/pull/20).
NVIDIA path is now way more efficient than before.

Secondly, adding controller support was a massive hurdle, requiring me
to start another project
[vimputti](https://github.com/DatCaptainHorse/vimputti) - which allows
simple virtual controller inputs in isolated containers. Well, it's not
simple, it includes LD_PRELOAD shims and other craziness, but the
library API is simple to use..

Thirdly, split runner image into 3 separate stages, base + build +
runtime, should help keep things in check in future, also added GitHub
Actions CI builds for v2 to v4 builds (hopefully they pass..).

Fourth, replaced the runner's runtime Steam patching with better and
simpler bubblewrap patch, massive thanks to `games-on-whales` to
figuring it out better!

Fifth, relay for once needed some changes, the new changes are still
mostly WIP, but I'll deal with them next time I have energy.. I'm spent
now. Needed to include these changes as relay needed a minor change to
allow rumble events to flow back to client peer.

Sixth.. tons of package updates, minor code improvements and the usual. 

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* End-to-end gamepad/controller support (attach/detach, buttons, sticks,
triggers, rumble) with client/server integration and virtual controller
plumbing.
  * Optional Prometheus metrics endpoint and WebTransport support.
  * Background vimputti manager process added for controller handling.

* **Improvements**
  * Multi-variant container image builds and streamlined runtime images.
  * Zero-copy video pipeline and encoder improvements for lower latency.
  * Updated Steam compat mapping and dependency/toolchain refreshes.

* **Bug Fixes**
* More robust GPU detection, input/fullscreen lifecycle,
startup/entrypoint, and container runtime fixes.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: DatCaptainHorse <DatCaptainHorse@users.noreply.github.com>
This commit is contained in:
Kristian Ollikainen
2025-10-20 11:20:05 +03:00
committed by GitHub
parent a3ee9aadd9
commit c62a22b552
62 changed files with 4203 additions and 2278 deletions

View File

@@ -21,6 +21,13 @@ chown_user_directory() {
echo "Error: Failed to change ownership of ${NESTRI_HOME} to ${NESTRI_USER}:${NESTRI_USER}" >&2
return 1
fi
# Also apply to .cache separately
if [[ -d "${NESTRI_HOME}/.cache" ]]; then
if ! $ENTCMD_PREFIX chown "${NESTRI_USER}:${NESTRI_USER}" "${NESTRI_HOME}/.cache" 2>/dev/null; then
echo "Error: Failed to change ownership of ${NESTRI_HOME}/.cache to ${NESTRI_USER}:${NESTRI_USER}" >&2
return 1
fi
fi
return 0
}
@@ -48,13 +55,13 @@ setup_namespaceless() {
# Ensures cache directory exists
setup_cache() {
log "Setting up NVIDIA driver cache directory at $CACHE_DIR..."
log "Setting up cache directory at $CACHE_DIR..."
mkdir -p "$CACHE_DIR" || {
log "Warning: Failed to create cache directory, continuing without cache."
log "Warning: Failed to create cache directory, continuing.."
return 1
}
$ENTCMD_PREFIX chown "${NESTRI_USER}:${NESTRI_USER}" "$CACHE_DIR" 2>/dev/null || {
log "Warning: Failed to set cache directory ownership, continuing..."
log "Warning: Failed to set cache directory ownership, continuing.."
}
}
@@ -223,7 +230,7 @@ main() {
# Start by getting the container we are running under
get_container_info || {
log "Warning: Failed to detect container information."
log "Warning: Failed to detect container information"
}
log_container_info
@@ -231,6 +238,9 @@ main() {
ENTCMD_PREFIX="sudo -E"
fi
# Setup cache now
setup_cache
# Configure SSH
if [ -n "${SSH_ENABLE_PORT+x}" ] && [ "${SSH_ENABLE_PORT:-0}" -ne 0 ] && \
[ -n "${SSH_ALLOWED_KEY+x}" ] && [ -n "${SSH_ALLOWED_KEY}" ]; then
@@ -244,14 +254,14 @@ main() {
# Get and detect GPU(s)
get_gpu_info || {
log "Error: Failed to detect GPU information."
log "Error: Failed to detect GPU information"
exit 1
}
log_gpu_info
# Handle NVIDIA GPU
if [[ -n "${vendor_devices[nvidia]:-}" ]]; then
log "NVIDIA GPU(s) detected, applying driver fix..."
log "NVIDIA GPU(s) detected, applying driver fix.."
# Determine NVIDIA driver version
local nvidia_driver_version=""
@@ -265,16 +275,15 @@ main() {
log "Error: Failed to determine NVIDIA driver version."
# Check for other GPU vendors before exiting
if [[ -n "${vendor_devices[amd]:-}" || -n "${vendor_devices[intel]:-}" ]]; then
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver."
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver"
else
log "No other GPUs detected, exiting due to NVIDIA driver version failure."
log "No other GPUs detected, exiting due to NVIDIA driver version failure"
exit 1
fi
else
log "Detected NVIDIA driver version: $nvidia_driver_version"
# Set up cache and get installer
setup_cache
# Get installer
local arch=$(uname -m)
local filename="NVIDIA-Linux-${arch}-${nvidia_driver_version}.run"
cd "$NVIDIA_INSTALLER_DIR" || {
@@ -284,9 +293,9 @@ main() {
get_nvidia_installer "$nvidia_driver_version" "$arch" || {
# Check for other GPU vendors before exiting
if [[ -n "${vendor_devices[amd]:-}" || -n "${vendor_devices[intel]:-}" ]]; then
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver."
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver"
else
log "No other GPUs detected, exiting due to NVIDIA installer failure."
log "No other GPUs detected, exiting due to NVIDIA installer failure"
exit 1
fi
}
@@ -295,9 +304,9 @@ main() {
install_nvidia_driver "$filename" || {
# Check for other GPU vendors before exiting
if [[ -n "${vendor_devices[amd]:-}" || -n "${vendor_devices[intel]:-}" ]]; then
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver."
log "Other GPUs (AMD or Intel) detected, continuing without NVIDIA driver"
else
log "No other GPUs detected, exiting due to NVIDIA driver installation failure."
log "No other GPUs detected, exiting due to NVIDIA driver installation failure"
exit 1
fi
}
@@ -305,14 +314,14 @@ main() {
fi
# Make sure gamescope has CAP_SYS_NICE capabilities if available
log "Checking for CAP_SYS_NICE availability..."
log "Checking for CAP_SYS_NICE availability.."
if capsh --print | grep -q "Current:.*cap_sys_nice"; then
log "Giving gamescope compositor CAP_SYS_NICE permissions..."
log "Giving gamescope compositor CAP_SYS_NICE permissions.."
setcap 'CAP_SYS_NICE+eip' /usr/bin/gamescope 2>/dev/null || {
log "Warning: Failed to set CAP_SYS_NICE on gamescope, continuing without it..."
log "Warning: Failed to set CAP_SYS_NICE on gamescope, continuing without it.."
}
else
log "Skipping CAP_SYS_NICE for gamescope, capability not available..."
log "Skipping CAP_SYS_NICE for gamescope, capability not available"
fi
# Handle user directory permissions
@@ -325,6 +334,19 @@ main() {
setup_namespaceless
fi
# Make sure /run/udev/ directory exists with /run/udev/control, needed for virtual controller support
if [[ ! -d "/run/udev" || ! -e "/run/udev/control" ]]; then
log "Creating /run/udev directory and control file..."
$ENTCMD_PREFIX mkdir -p /run/udev || {
log "Error: Failed to create /run/udev directory"
exit 1
}
$ENTCMD_PREFIX touch /run/udev/control || {
log "Error: Failed to create /run/udev/control file"
exit 1
}
fi
# Switch to nestri runner entrypoint
log "Switching to application startup entrypoint..."
if [[ ! -f /etc/nestri/entrypoint_nestri.sh ]]; then
@@ -339,6 +361,6 @@ main() {
}
# Trap signals for clean exit
trap 'log "Received termination signal, exiting..."; exit 1' SIGINT SIGTERM
trap 'log "Received termination signal, exiting.."; exit 0' SIGINT SIGTERM
main