selkies-entrypoint.sh 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. #!/bin/bash
  2. # This Source Code Form is subject to the terms of the Mozilla Public
  3. # License, v. 2.0. If a copy of the MPL was not distributed with this
  4. # file, You can obtain one at https://mozilla.org/MPL/2.0/.
  5. set -Eeuo pipefail
  6. bool_is_true() {
  7. case "${1,,}" in
  8. 1|true|yes|on) return 0 ;;
  9. *) return 1 ;;
  10. esac
  11. }
  12. # Runtime and display configuration.
  13. export DISPLAY="${DISPLAY:-:20}"
  14. export PIPEWIRE_LATENCY="${PIPEWIRE_LATENCY:-128/48000}"
  15. export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/tmp/runtime-${USER:-desktop}}"
  16. export PIPEWIRE_RUNTIME_DIR="${PIPEWIRE_RUNTIME_DIR:-${XDG_RUNTIME_DIR}}"
  17. export PULSE_RUNTIME_PATH="${PULSE_RUNTIME_PATH:-${XDG_RUNTIME_DIR}/pulse}"
  18. export PULSE_SERVER="${PULSE_SERVER:-unix:${PULSE_RUNTIME_PATH}/native}"
  19. install -d -m 0700 "${XDG_RUNTIME_DIR}"
  20. # Enable the optional joystick interposer only when it is actually installed.
  21. SELKIES_INTERPOSER_PATH="$(
  22. find /usr/lib /usr/lib64 /usr/local/lib \
  23. -name 'selkies_joystick_interposer.so' \
  24. -print -quit 2>/dev/null || true
  25. )"
  26. if [[ -n "${SELKIES_INTERPOSER_PATH}" ]]; then
  27. export LD_PRELOAD="${SELKIES_INTERPOSER_PATH}${LD_PRELOAD:+:${LD_PRELOAD}}"
  28. export SDL_JOYSTICK_DEVICE="${SDL_JOYSTICK_DEVICE:-/dev/input/js0}"
  29. echo "Joystick interposer enabled: ${SELKIES_INTERPOSER_PATH}"
  30. fi
  31. # NVIDIA NVRTC is not always mounted by the NVIDIA container runtime.
  32. # Keep the upstream-compatible runtime download, but place it in a
  33. # user-writable directory instead of modifying /usr at container startup.
  34. install_nvrtc() {
  35. bool_is_true "${SELKIES_DOWNLOAD_NVRTC:-true}" || return 0
  36. command -v nvidia-smi >/dev/null 2>&1 || return 0
  37. nvidia-smi >/dev/null 2>&1 || return 0
  38. if ldconfig -p 2>/dev/null | grep -q 'libnvrtc\.so'; then
  39. echo "NVRTC already available"
  40. return 0
  41. fi
  42. local cuda_version cuda_major nvrtc_arch multiarch
  43. local nvrtc_url nvrtc_archive fallback_version destination
  44. cuda_version="$(
  45. nvidia-smi --version |
  46. awk -F: '/CUDA Version/{gsub(/[[:space:]]/, "", $2); print $2; exit}'
  47. )"
  48. if [[ -z "${cuda_version}" ]]; then
  49. echo "WARNING: NVIDIA is available, but its CUDA compatibility version could not be detected" >&2
  50. return 0
  51. fi
  52. cuda_major="${cuda_version%%.*}"
  53. if [[ "${cuda_major}" =~ ^[0-9]+$ ]] && (( cuda_major >= 13 )); then
  54. cuda_version="12.9"
  55. fi
  56. nvrtc_arch="$(
  57. dpkg --print-architecture |
  58. sed -e 's/arm64/sbsa/' \
  59. -e 's/ppc64el/ppc64le/' \
  60. -e 's/i.*86/x86/' \
  61. -e 's/amd64/x86_64/' \
  62. -e 's/unknown/x86_64/'
  63. )"
  64. multiarch="$(
  65. dpkg --print-architecture |
  66. sed -e 's/arm64/aarch64-linux-gnu/' \
  67. -e 's/armhf/arm-linux-gnueabihf/' \
  68. -e 's/riscv64/riscv64-linux-gnu/' \
  69. -e 's/ppc64el/powerpc64le-linux-gnu/' \
  70. -e 's/s390x/s390x-linux-gnu/' \
  71. -e 's/i.*86/i386-linux-gnu/' \
  72. -e 's/amd64/x86_64-linux-gnu/' \
  73. -e 's/unknown/x86_64-linux-gnu/'
  74. )"
  75. nvrtc_url="https://developer.download.nvidia.com/compute/cuda/redist/cuda_nvrtc/linux-${nvrtc_arch}/"
  76. nvrtc_archive="$(
  77. curl -fsSL "${nvrtc_url}" |
  78. grep -oP "(?<=href=')cuda_nvrtc-linux-${nvrtc_arch}-${cuda_version}\.[0-9]+-archive\.tar\.xz" |
  79. sort -V |
  80. tail -n 1 ||
  81. true
  82. )"
  83. if [[ -z "${nvrtc_archive}" ]]; then
  84. fallback_version="${cuda_version}.0"
  85. nvrtc_archive="$(
  86. {
  87. curl -fsSL "${nvrtc_url}" |
  88. grep -oP "(?<=href=')cuda_nvrtc-linux-${nvrtc_arch}-.*?\.tar\.xz" ||
  89. true
  90. echo "cuda_nvrtc-linux-${nvrtc_arch}-${fallback_version}-archive.tar.xz"
  91. } |
  92. sort -V |
  93. grep -B 1 --fixed-strings "${fallback_version}" |
  94. head -n 1 ||
  95. true
  96. )"
  97. fi
  98. if [[ -z "${nvrtc_archive}" ]]; then
  99. echo "WARNING: no compatible NVRTC archive found for CUDA ${cuda_version}" >&2
  100. return 0
  101. fi
  102. destination="${NVRTC_DEST_PREFIX:-${XDG_CACHE_HOME:-${HOME:-/tmp}/.cache}/selkies/nvrtc}/lib/${multiarch}"
  103. install -d -m 0755 "${destination}"
  104. if compgen -G "${destination}/libnvrtc*" >/dev/null; then
  105. echo "Using cached NVRTC runtime from ${destination}"
  106. export LD_LIBRARY_PATH="${destination}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
  107. return 0
  108. fi
  109. echo "Installing NVRTC runtime: ${nvrtc_archive}"
  110. rm -rf /tmp/selkies-nvrtc
  111. install -d /tmp/selkies-nvrtc
  112. curl -fsSL "${nvrtc_url}${nvrtc_archive}" |
  113. tar -xJf - -C /tmp/selkies-nvrtc
  114. find /tmp/selkies-nvrtc -type f -name 'libnvrtc*' \
  115. -exec install -m 0755 {} "${destination}/" \;
  116. rm -rf /tmp/selkies-nvrtc
  117. export LD_LIBRARY_PATH="${destination}${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}"
  118. }
  119. install_nvrtc
  120. echo "Waiting for X socket ${DISPLAY}"
  121. until [[ -S "/tmp/.X11-unix/X${DISPLAY#*:}" ]]; do
  122. sleep 0.5
  123. done
  124. echo "Waiting for PipeWire-Pulse socket ${PULSE_RUNTIME_PATH}/native"
  125. until [[ -S "${PULSE_RUNTIME_PATH}/native" ]]; do
  126. sleep 0.5
  127. done
  128. # The current Selkies wheel contains the backend and HTML5 client.
  129. # WebSocket transport needs only this one listening port.
  130. export SELKIES_MODE="${SELKIES_MODE:-websockets}"
  131. export SELKIES_ENCODER="${SELKIES_ENCODER:-h264enc}"
  132. export SELKIES_ENABLE_RESIZE="${SELKIES_ENABLE_RESIZE:-false}"
  133. export SELKIES_ENABLE_BASIC_AUTH="${SELKIES_ENABLE_BASIC_AUTH:-true}"
  134. export SELKIES_BASIC_AUTH_USER="${SELKIES_BASIC_AUTH_USER:-${USER:-desktop}}"
  135. export SELKIES_BASIC_AUTH_PASSWORD="${SELKIES_BASIC_AUTH_PASSWORD:-${PASSWD:-mypasswd}}"
  136. echo "Starting Selkies on ${SELKIES_ADDR:-0.0.0.0}:${SELKIES_PORT:-8080}"
  137. exec selkies \
  138. --addr="${SELKIES_ADDR:-0.0.0.0}" \
  139. --port="${SELKIES_PORT:-8080}" \
  140. --enable_https="false" \
  141. --mode="${SELKIES_MODE}" \
  142. --encoder="${SELKIES_ENCODER}" \
  143. --enable_resize="${SELKIES_ENABLE_RESIZE}" \
  144. --enable_basic_auth="${SELKIES_ENABLE_BASIC_AUTH}" \
  145. "$@"