sunshine-entrypoint.sh 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #!/bin/bash
  2. set -euo pipefail
  3. # ============================================================
  4. # NVIDIA driver version check
  5. # ============================================================
  6. if command -v nvidia-smi >/dev/null 2>&1; then
  7. ACTUAL_NVIDIA_DRIVER_VERSION="$(
  8. nvidia-smi \
  9. --query-gpu=driver_version \
  10. --format=csv,noheader \
  11. | head -n1 \
  12. | tr -d '[:space:]'
  13. )"
  14. if [ -n "${EXPECTED_NVIDIA_DRIVER_VERSION:-}" ]; then
  15. if [ "${ACTUAL_NVIDIA_DRIVER_VERSION}" != "${EXPECTED_NVIDIA_DRIVER_VERSION}" ]; then
  16. echo
  17. echo "============================================================"
  18. echo "[sunshine] WARNING: NVIDIA DRIVER VERSION MISMATCH"
  19. echo "============================================================"
  20. echo "[sunshine] GPU Operator driver : ${ACTUAL_NVIDIA_DRIVER_VERSION}"
  21. echo "[sunshine] Image expects : ${EXPECTED_NVIDIA_DRIVER_VERSION}"
  22. echo "[sunshine] i386 packages : ${NVIDIA_I386_PACKAGE_VERSION:-unknown}"
  23. echo
  24. echo "[sunshine] 32-bit OpenGL/Vulkan may not work correctly."
  25. echo "[sunshine] Update the NVIDIA versions at the top of the Dockerfile"
  26. echo "[sunshine] and rebuild this image."
  27. echo "============================================================"
  28. echo
  29. else
  30. echo "[sunshine] NVIDIA driver version OK: ${ACTUAL_NVIDIA_DRIVER_VERSION}"
  31. fi
  32. fi
  33. else
  34. echo "[sunshine] WARNING: nvidia-smi not found; unable to check NVIDIA driver version."
  35. fi
  36. echo "=============================================================="
  37. echo " Sunshine Gaming Desktop"
  38. echo "=============================================================="
  39. echo
  40. echo "Starting existing desktop stack..."
  41. # On conserve temporairement tout le mécanisme Selkies existant :
  42. # Xorg NVIDIA, XFCE, PipeWire, WirePlumber, D-Bus, etc.
  43. /usr/bin/supervisord -c /etc/supervisord.conf &
  44. SUPERVISOR_PID=$!
  45. cleanup() {
  46. echo "Stopping supervisor..."
  47. kill "${SUPERVISOR_PID}" 2>/dev/null || true
  48. wait "${SUPERVISOR_PID}" 2>/dev/null || true
  49. }
  50. trap cleanup EXIT TERM INT
  51. echo
  52. echo "Waiting for Xorg on ${DISPLAY}..."
  53. for i in $(seq 1 60); do
  54. if xdpyinfo -display "${DISPLAY}" >/dev/null 2>&1; then
  55. echo "Xorg is ready."
  56. break
  57. fi
  58. if ! kill -0 "${SUPERVISOR_PID}" 2>/dev/null; then
  59. echo "ERROR: supervisord exited before Xorg became available."
  60. exit 1
  61. fi
  62. if [ "${i}" -eq 60 ]; then
  63. echo "ERROR: Xorg did not become ready."
  64. exit 1
  65. fi
  66. sleep 1
  67. done
  68. # Restore NVIDIA 32-bit userspace libraries after NVIDIA Container Toolkit
  69. # has performed its runtime driver injection.
  70. if [ ! -e /usr/lib/i386-linux-gnu/libGLX_nvidia.so.0 ] \
  71. && [ -d /opt/nvidia-i386/usr/lib/i386-linux-gnu ]; then
  72. echo "[sunshine] Restoring NVIDIA i386 userspace libraries..."
  73. sudo mkdir -p /usr/lib/i386-linux-gnu
  74. sudo cp -a \
  75. /opt/nvidia-i386/usr/lib/i386-linux-gnu/. \
  76. /usr/lib/i386-linux-gnu/
  77. sudo /sbin/ldconfig
  78. fi
  79. echo
  80. echo "GPU:"
  81. nvidia-smi --query-gpu=name,driver_version --format=csv,noheader || true
  82. echo
  83. echo "Display:"
  84. xdpyinfo -display "${DISPLAY}" \
  85. | grep -E 'dimensions:|resolution:' \
  86. || true
  87. SUNSHINE_CONFIG_DIR="${HOME}/.config/sunshine"
  88. SUNSHINE_CONFIG="${SUNSHINE_CONFIG_DIR}/sunshine.conf"
  89. mkdir -p "${SUNSHINE_CONFIG_DIR}"
  90. touch "${SUNSHINE_CONFIG}"
  91. set_sunshine_option() {
  92. local key="$1"
  93. local value="$2"
  94. if grep -qE "^[[:space:]]*${key}[[:space:]]*=" "${SUNSHINE_CONFIG}"; then
  95. sed -i -E \
  96. "s|^[[:space:]]*${key}[[:space:]]*=.*|${key} = ${value}|" \
  97. "${SUNSHINE_CONFIG}"
  98. else
  99. printf '%s = %s\n' "${key}" "${value}" >> "${SUNSHINE_CONFIG}"
  100. fi
  101. }
  102. # Option forcée dans la config de Sunshine
  103. set_sunshine_option "system_tray" "disabled"
  104. set_sunshine_option "capture" "nvfbc"
  105. set_sunshine_option "encoder" "nvenc"
  106. echo "Sunshine configuration:"
  107. cat "${HOME}/.config/sunshine/sunshine.conf"
  108. echo
  109. echo "Starting Sunshine..."
  110. /usr/bin/sunshine &
  111. SUNSHINE_PID=$!
  112. cleanup() {
  113. echo "Stopping Sunshine..."
  114. kill "${SUNSHINE_PID}" 2>/dev/null || true
  115. wait "${SUNSHINE_PID}" 2>/dev/null || true
  116. echo "Stopping supervisor..."
  117. kill "${SUPERVISOR_PID}" 2>/dev/null || true
  118. wait "${SUPERVISOR_PID}" 2>/dev/null || true
  119. }
  120. trap cleanup EXIT TERM INT
  121. echo
  122. echo "Waiting for Sunshine virtual input devices..."
  123. for i in $(seq 1 30); do
  124. if grep -q 'Name="Mouse passthrough"' /proc/bus/input/devices \
  125. && grep -q 'Name="Keyboard passthrough"' /proc/bus/input/devices; then
  126. echo "Sunshine virtual mouse and keyboard detected."
  127. break
  128. fi
  129. if ! kill -0 "${SUNSHINE_PID}" 2>/dev/null; then
  130. echo "ERROR: Sunshine exited before creating input devices."
  131. wait "${SUNSHINE_PID}"
  132. exit $?
  133. fi
  134. sleep 1
  135. done
  136. echo
  137. echo "Restarting Xorg so it picks up Sunshine virtual input devices..."
  138. supervisorctl stop entrypoint || true
  139. pkill -TERM -x Xorg || true
  140. for i in $(seq 1 20); do
  141. if ! pgrep -x Xorg >/dev/null; then
  142. break
  143. fi
  144. sleep 0.5
  145. done
  146. if pgrep -x Xorg >/dev/null; then
  147. echo "Xorg did not stop cleanly, sending SIGKILL..."
  148. pkill -KILL -x Xorg || true
  149. sleep 1
  150. fi
  151. echo "Starting desktop/Xorg again..."
  152. supervisorctl start entrypoint
  153. echo "Waiting for restarted Xorg..."
  154. for i in $(seq 1 60); do
  155. if xdpyinfo -display "${DISPLAY}" >/dev/null 2>&1; then
  156. echo "Restarted Xorg is ready."
  157. break
  158. fi
  159. sleep 1
  160. done
  161. echo
  162. echo "Checking Sunshine input devices in Xorg log..."
  163. grep -Ei \
  164. 'Mouse passthrough|Keyboard passthrough|libinput' \
  165. /home/ubuntu/.local/share/xorg/Xorg.20.log \
  166. | tail -30 \
  167. || true
  168. # No more sudo privilege
  169. sudo rm -f /etc/sudoers.d/ubuntu
  170. echo
  171. echo "Sunshine Gaming Desktop ready."
  172. wait "${SUNSHINE_PID}"