feat: WIP s6-overlay and friends

This commit is contained in:
DatCaptainHorse
2026-02-19 18:02:10 +02:00
parent b743dab332
commit 34afd371ad
96 changed files with 2340 additions and 1063 deletions

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,25 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# check if NESTRI_LAUNCH_CMD is unset or empty
if [[ -z "${NESTRI_LAUNCH_CMD:-}" ]]; then
# exit with 0 so s6 doesn't think the service failed and try to restart it repeatedly
exit 0
fi
export LD_PRELOAD="/usr/lib64/libvimputti_shim.so:/usr/lib32/libvimputti_shim.so"
s6-setuidgid ${NESTRI_USER} ${NESTRI_LAUNCH_CMD} &
PROCESS_PID=$!
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,44 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# check if NESTRI_LAUNCH_COMPOSITOR is unset or empty
if [[ -z "${NESTRI_LAUNCH_COMPOSITOR:-}" ]]; then
# exit with 0 so s6 doesn't think the service failed and try to restart it repeatedly
exit 0
fi
export LD_PRELOAD="/usr/lib64/libvimputti_shim.so:/usr/lib32/libvimputti_shim.so"
# Set socket based on compositor type
COMPOSITOR_SOCKET="${NESTRI_XDG_RUNTIME_DIR}/wayland-0"
# Check if this is gamescope
if [[ "${NESTRI_LAUNCH_COMPOSITOR}" == *"gamescope"* ]]; then
COMPOSITOR_SOCKET="${NESTRI_XDG_RUNTIME_DIR}/gamescope-0"
fi
# remove possibly stale socket
rm -f "${COMPOSITOR_SOCKET}"
# expand internal variables
FINAL_LAUNCH_COMPOSITOR=$(echo "${NESTRI_LAUNCH_COMPOSITOR}" | envsubst)
WAYLAND_DISPLAY=wayland-1 s6-setuidgid ${NESTRI_USER} $FINAL_LAUNCH_COMPOSITOR &
PROCESS_PID=$!
# wait for socket
while ! test -S "${COMPOSITOR_SOCKET}"; do
sleep 1
done
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,25 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# remove possibly stale socket
rm -f "${NESTRI_XDG_RUNTIME_DIR}/bus"
s6-setuidgid ${NESTRI_USER} dbus-daemon --session --address=unix:path="${NESTRI_XDG_RUNTIME_DIR}/bus" --nofork --nopidfile &
PROCESS_PID=$!
# wait for socket
while ! test -S "${NESTRI_XDG_RUNTIME_DIR}/bus"; do
sleep 0.5
done
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,25 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# remove possibly stale socket
rm -f "/run/dbus/system_bus_socket"
dbus-daemon --system --address=unix:path="/run/dbus/system_bus_socket" --nofork --nopidfile &
PROCESS_PID=$!
# wait for socket
while ! test -S "/run/dbus/system_bus_socket"; do
sleep 0.5
done
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1,238 @@
#!/command/with-contenv bash
set -euo pipefail
# Common helpers as requirement
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
echo "Error: Common script not found at /etc/nestri/common.sh" >&2
exit 1
fi
# Configuration
CACHE_DIR="${NESTRI_HOME}/.cache/nestri"
NVIDIA_INSTALLER_DIR="/tmp"
# Methods #
# Ensures user ownership across directories
handle_user_permissions() {
if ! chown "${NESTRI_USER}:${NESTRI_USER}" "${NESTRI_HOME}" 2>/dev/null; then
echo "Error: Failed to change ownership of ${NESTRI_HOME} to ${NESTRI_USER}:${NESTRI_USER}" >&2
return 1
fi
# Also apply to .cache
if [[ -d "${NESTRI_HOME}/.cache" ]]; then
if ! 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
}
# Prepares environment for namespace-less applications (like Steam)
setup_namespaceless() {
rm -f /run/systemd/container || true
mkdir -p /run/pressure-vessel || true
}
# Ensures cache directory exists
setup_cache() {
log "Setting up cache directory at $CACHE_DIR..."
mkdir -p "$CACHE_DIR" || {
log "Warning: Failed to create cache directory, continuing.."
return 1
}
chown "${NESTRI_USER}:${NESTRI_USER}" "$CACHE_DIR" 2>/dev/null || {
log "Warning: Failed to set cache directory ownership, continuing.."
}
}
# Grabs NVIDIA driver installer
get_nvidia_installer() {
local driver_version="$1"
local arch="$2"
local filename="NVIDIA-Linux-${arch}-${driver_version}.run"
local cached_file="${CACHE_DIR}/${filename}"
local tmp_file="${NVIDIA_INSTALLER_DIR}/${filename}"
# Check cache
if [[ -f "$cached_file" ]]; then
log "Found cached NVIDIA installer at $cached_file."
cp "$cached_file" "$tmp_file" || {
log "Warning: Failed to copy cached installer, proceeding with download."
rm -f "$cached_file" 2>/dev/null
}
fi
# Download if not in tmp
if [[ ! -f "$tmp_file" ]]; then
log "Downloading NVIDIA driver installer ($filename)..."
local urls=(
"https://international.download.nvidia.com/XFree86/Linux-${arch}/${driver_version}/${filename}"
"https://international.download.nvidia.com/tesla/${driver_version}/${filename}"
)
local success=0
for url in "${urls[@]}"; do
if wget -q --show-progress "$url" -O "$tmp_file"; then
success=1
break
fi
log "Failed to download from $url, trying next source..."
done
if [[ "$success" -eq 0 ]]; then
log "Error: Failed to download NVIDIA driver from all sources."
return 1
fi
# Cache the downloaded file
cp "$tmp_file" "$cached_file" 2>/dev/null && \
chown "${NESTRI_USER}:${NESTRI_USER}" "$cached_file" 2>/dev/null || \
log "Warning: Failed to cache NVIDIA driver, continuing..."
fi
chmod +x "$tmp_file" || {
log "Error: Failed to make NVIDIA installer executable."
return 1
}
return 0
}
# Installs the NVIDIA driver
install_nvidia_driver() {
local filename="$1"
log "Installing NVIDIA driver components from $filename..."
bash ./"$filename" \
--silent \
--skip-depmod \
--skip-module-unload \
--no-kernel-module \
--install-compat32-libs \
--no-nouveau-check \
--no-nvidia-modprobe \
--no-systemd \
--no-rpms \
--no-backup \
--no-distro-scripts \
--no-libglx-indirect \
--no-install-libglvnd \
--no-check-for-alternate-installs || {
log "Error: NVIDIA driver installation failed."
return 1
}
log "NVIDIA driver installation completed."
return 0
}
log_container_info() {
if ! declare -p container_runtime &>/dev/null; then
log "Warning: container_runtime is not defined"
return
fi
if [[ "${container_runtime:-none}" != "none" ]]; then
log "Detected container:"
log "> ${container_runtime}"
else
log "No container runtime detected"
fi
}
log_gpu_info() {
if ! declare -p vendor_devices &>/dev/null; then
log "Warning: vendor_devices array is not defined"
return
fi
log "Detected GPUs:"
for vendor in "${!vendor_devices[@]}"; do
log "> $vendor: ${vendor_devices[$vendor]}"
done
}
# Main #
# Start by getting the container we are running under
get_container_info || {
log "Warning: Failed to detect container information"
}
log_container_info
# Setup cache now
setup_cache
# Get and detect GPU(s)
get_gpu_info || {
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.."
# Determine NVIDIA driver version
nvidia_driver_version=""
if [[ -f "/proc/driver/nvidia/version" ]]; then
nvidia_driver_version=$(awk '/NVIDIA/ {for(i=1;i<=NF;i++) if ($i ~ /^[0-9]+\.[0-9\.]+/) {print $i; exit}}' /proc/driver/nvidia/version | head -n1)
elif command -v nvidia-smi >/dev/null 2>&1; then
nvidia_driver_version=$(nvidia-smi --version | grep -i 'driver version' | cut -d: -f2 | tr -d ' ')
fi
if [[ -z "$nvidia_driver_version" ]]; then
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"
else
log "No other GPUs detected, exiting due to NVIDIA driver version failure"
exit 1
fi
else
log "Detected NVIDIA driver version: $nvidia_driver_version"
# Get installer
arch=$(uname -m)
filename="NVIDIA-Linux-${arch}-${nvidia_driver_version}.run"
cd "$NVIDIA_INSTALLER_DIR" || {
log "Error: Failed to change to $NVIDIA_INSTALLER_DIR."
exit 1
}
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"
else
log "No other GPUs detected, exiting due to NVIDIA installer failure"
exit 1
fi
}
# Install driver
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"
else
log "No other GPUs detected, exiting due to NVIDIA driver installation failure"
exit 1
fi
}
fi
fi
# Handle user permissions
log "Ensuring user permissions..."
handle_user_permissions || exit 1
# Setup namespaceless env if needed for container runtime
if [[ "$container_runtime" != "podman" ]]; then
log "Applying namespace-less configuration"
setup_namespaceless
fi

View File

@@ -0,0 +1 @@
oneshot

View File

@@ -0,0 +1 @@
/etc/s6-overlay/s6-rc.d/init/run

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,25 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# remove possibly stale socket
rm -f "${NESTRI_XDG_RUNTIME_DIR}/wayland-1"
s6-setuidgid ${NESTRI_USER} nestri-server $NESTRI_PARAMS &
PROCESS_PID=$!
# wait for socket
while ! test -S "${NESTRI_XDG_RUNTIME_DIR}/wayland-1"; do
sleep 1
done
# notify
printf 'ready\n' >&3
# wait till process exists
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,26 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# remove possibly stale socket
rm -rf "${NESTRI_XDG_RUNTIME_DIR}/pulse"
s6-setuidgid ${NESTRI_USER} pipewire-pulse &
PROCESS_PID=$!
# wait for socket
while ! test -S "${NESTRI_XDG_RUNTIME_DIR}/pulse/native"; do
sleep 0.5
done
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,26 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
# remove possibly stale socket
rm -f "${NESTRI_XDG_RUNTIME_DIR}/pipewire-0"
s6-setuidgid ${NESTRI_USER} pipewire &
PROCESS_PID=$!
# wait for socket
while ! test -S "${NESTRI_XDG_RUNTIME_DIR}/pipewire-0"; do
sleep 0.5
done
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,27 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
export VIMPUTTI_PATH="${NESTRI_VIMPUTTI_PATH}"
# remove possibly stale socket
rm -f "/tmp/vimputti-0"
s6-setuidgid ${NESTRI_USER} vimputti-manager &
PROCESS_PID=$!
# wait for socket
while ! test -S "/tmp/vimputti-0"; do
sleep 1
done
# notify
printf 'ready\n' >&3
# wait till process exists
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun

View File

@@ -0,0 +1 @@
3

View File

@@ -0,0 +1,20 @@
#!/command/with-contenv bash
set -euo pipefail
if [[ -f /etc/nestri/common.sh ]]; then
source /etc/nestri/common.sh
else
exit 1
fi
s6-setuidgid ${NESTRI_USER} wireplumber &
PROCESS_PID=$!
# safety sleep for wireplumber
sleep 0.5
# notify
printf 'ready\n' >&3
# wait till process exits
wait "${PROCESS_PID}"

View File

@@ -0,0 +1 @@
longrun