Skip to content

Commit 4814c88

Browse files
feat: add KasmVNC audio, hw3d and Zink GPU acceleration
Audio fix: PulseAudio null-sink virtual en imagenes Docker y en todos los startup scripts (fix inmediato para workspaces existentes al reiniciar). Sin null-sink, PulseAudio arrancaba sin sinks en contenedores Docker y KasmVNC no podia capturar audio via WebRTC. hw3d (Intel/AMD): añadida deteccion y configuracion de kasmvnc-hw3d en Developer, AdvancedHostDANGER, OpenClaw y DeveloperAndroid. Ya existia en Maker. Activa hw3d solo cuando hay /dev/dri/renderD128 accesible y no hay NVIDIA (DRI3/GBM no compatible con driver propietario). Zink (NVIDIA): añadido soporte Zink (OpenGL sobre Vulkan) en los 5 templates. Cuando se detecta NVIDIA, escribe MESA_LOADER_DRIVER_OVERRIDE=zink y GALLIUM_DRIVER=zink en ~/.xsessionrc para que las apps de la sesion X usen OpenGL via Vulkan en lugar de intentar DRI3. Paquetes libvulkan1 y mesa-vulkan-drivers añadidos a las imagenes Developer, Designer y DeveloperAndroid. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f4f1710 commit 4814c88

8 files changed

Lines changed: 256 additions & 2 deletions

File tree

Docker-Images/Designer/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,19 @@ RUN dpkg --add-architecture i386 && \
8080
alsa-utils \
8181
&& rm -rf /var/lib/apt/lists/*
8282

83+
# PulseAudio: null-sink virtual para contenedores sin hardware de audio
84+
# Permite que KasmVNC capture audio via el monitor de este sink
85+
RUN mkdir -p /etc/pulse/default.pa.d && \
86+
printf 'load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable"\nset-default-sink vcable\n' \
87+
> /etc/pulse/default.pa.d/10-null-sink.pa
88+
89+
# Vulkan loader + Mesa Vulkan drivers (incluye Zink: OpenGL sobre Vulkan para NVIDIA en KasmVNC)
90+
RUN apt-get update && \
91+
apt-get install -y --no-install-recommends \
92+
libvulkan1 \
93+
mesa-vulkan-drivers \
94+
&& rm -rf /var/lib/apt/lists/*
95+
8396
# OrcaSlicer (AppImage), LaserGRBL (Wine), OpenCode Desktop y VisiCut (.deb)
8497
RUN <<'EOSH'
8598
set -e

Docker-Images/Developer/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,19 @@ RUN apt-get update && \
7070
# Configuración FUSE para permitir AppImages (allow_other)
7171
RUN echo "user_allow_other" > /etc/fuse.conf
7272

73+
# PulseAudio: null-sink virtual para contenedores sin hardware de audio
74+
# Permite que KasmVNC capture audio via el monitor de este sink
75+
RUN mkdir -p /etc/pulse/default.pa.d && \
76+
printf 'load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable"\nset-default-sink vcable\n' \
77+
> /etc/pulse/default.pa.d/10-null-sink.pa
78+
79+
# Vulkan loader + Mesa Vulkan drivers (incluye Zink: OpenGL sobre Vulkan para NVIDIA en KasmVNC)
80+
RUN apt-get update && \
81+
apt-get install -y --no-install-recommends \
82+
libvulkan1 \
83+
mesa-vulkan-drivers \
84+
&& rm -rf /var/lib/apt/lists/*
85+
7386
# KasmVNC viene como módulo de Coder; solo dejamos KDE como session manager
7487
RUN update-alternatives --set x-session-manager /usr/bin/startplasma-x11 || true
7588

Docker-Images/DeveloperAndroid/Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ RUN dpkg --add-architecture i386 && \
5959
ssl-cert \
6060
&& rm -rf /var/lib/apt/lists/*
6161

62+
# PulseAudio: null-sink virtual para contenedores sin hardware de audio
63+
# Permite que KasmVNC capture audio via el monitor de este sink
64+
RUN mkdir -p /etc/pulse/default.pa.d && \
65+
printf 'load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable"\nset-default-sink vcable\n' \
66+
> /etc/pulse/default.pa.d/10-null-sink.pa
67+
68+
# Vulkan loader + Mesa Vulkan drivers (incluye Zink: OpenGL sobre Vulkan para NVIDIA en KasmVNC)
69+
RUN apt-get update && \
70+
apt-get install -y --no-install-recommends \
71+
libvulkan1 \
72+
mesa-vulkan-drivers \
73+
&& rm -rf /var/lib/apt/lists/*
74+
6275
# GitHub CLI (repositorio oficial)
6376
RUN install -m 0755 -d /etc/apt/keyrings && \
6477
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | gpg --dearmor -o /etc/apt/keyrings/githubcli-archive-keyring.gpg && \

workspaces/AdvancedHostDANGER/main.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,16 @@ PULSECFG
183183
if ! pgrep -u "$USER" pulseaudio >/dev/null 2>&1; then
184184
pulseaudio --start --exit-idle-time=-1 || true
185185
fi
186+
# Cargar null-sink virtual para que KasmVNC pueda capturar audio
187+
# (en contenedores Docker no hay hardware de audio; el null-sink actua como sink por defecto)
188+
for _pa_try in 1 2 3; do
189+
if pactl load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable" 2>/dev/null; then
190+
pactl set-default-sink vcable 2>/dev/null || true
191+
break
192+
fi
193+
sleep 1
194+
done
195+
unset _pa_try
186196
187197
# Asegurar /home/coder como HOME efectivo incluso si se ejecuta como root
188198
sudo mkdir -p /home/coder
@@ -208,6 +218,45 @@ PULSECFG
208218
fi
209219
fi
210220
done
221+
222+
# Activar aceleracion 3D en KasmVNC solo cuando la ruta GBM/DRI es viable.
223+
# Nota: con driver NVIDIA propietario suele fallar con "Failed to create gbm".
224+
mkdir -p "$HOME/.vnc"
225+
KASM_USER_CFG="$HOME/.vnc/kasmvnc.yaml"
226+
KASM_MANAGED_TAG="# managed-by-advancedhost-template: kasmvnc-hw3d"
227+
HAS_RENDER_NODE=false
228+
if [ -e /dev/dri/renderD128 ] && [ -r /dev/dri/renderD128 ] && [ -w /dev/dri/renderD128 ]; then
229+
HAS_RENDER_NODE=true
230+
fi
231+
HAS_NVIDIA=false
232+
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
233+
HAS_NVIDIA=true
234+
fi
235+
236+
if [ "$HAS_RENDER_NODE" = "true" ] && [ "$HAS_NVIDIA" = "false" ]; then
237+
cat > "$KASM_USER_CFG" <<'KASMGPUCFG'
238+
# managed-by-advancedhost-template: kasmvnc-hw3d
239+
desktop:
240+
gpu:
241+
hw3d: true
242+
drinode: /dev/dri/renderD128
243+
KASMGPUCFG
244+
elif [ "$HAS_NVIDIA" = "true" ]; then
245+
# NVIDIA propietario: hw3d no soporta DRI3/GBM; configurar Zink (OpenGL→Vulkan→GPU)
246+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
247+
rm -f "$KASM_USER_CFG"
248+
fi
249+
ZINK_TAG="# managed-by-advancedhost-template: zink-nvidia"
250+
if ! grep -qF "$ZINK_TAG" "$HOME/.xsessionrc" 2>/dev/null; then
251+
printf '%s\nexport MESA_LOADER_DRIVER_OVERRIDE=zink\nexport GALLIUM_DRIVER=zink\n' \
252+
"$ZINK_TAG" >> "$HOME/.xsessionrc"
253+
fi
254+
else
255+
# Sin render node accesible: limpiar config gestionada
256+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
257+
rm -f "$KASM_USER_CFG"
258+
fi
259+
fi
211260
fi
212261
213262
# Asegurar permisos de pipx para el usuario actual

workspaces/Developer/main.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,16 @@ PULSECFG
226226
if ! pgrep -u "$USER" pulseaudio >/dev/null 2>&1; then
227227
pulseaudio --start --exit-idle-time=-1 || true
228228
fi
229+
# Cargar null-sink virtual para que KasmVNC pueda capturar audio
230+
# (en contenedores Docker no hay hardware de audio; el null-sink actua como sink por defecto)
231+
for _pa_try in 1 2 3; do
232+
if pactl load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable" 2>/dev/null; then
233+
pactl set-default-sink vcable 2>/dev/null || true
234+
break
235+
fi
236+
sleep 1
237+
done
238+
unset _pa_try
229239
230240
# Asegurar /home/coder como HOME efectivo incluso si se ejecuta como root
231241
sudo mkdir -p /home/coder
@@ -251,6 +261,45 @@ PULSECFG
251261
fi
252262
fi
253263
done
264+
265+
# Activar aceleracion 3D en KasmVNC solo cuando la ruta GBM/DRI es viable.
266+
# Nota: con driver NVIDIA propietario suele fallar con "Failed to create gbm".
267+
mkdir -p "$HOME/.vnc"
268+
KASM_USER_CFG="$HOME/.vnc/kasmvnc.yaml"
269+
KASM_MANAGED_TAG="# managed-by-developer-template: kasmvnc-hw3d"
270+
HAS_RENDER_NODE=false
271+
if [ -e /dev/dri/renderD128 ] && [ -r /dev/dri/renderD128 ] && [ -w /dev/dri/renderD128 ]; then
272+
HAS_RENDER_NODE=true
273+
fi
274+
HAS_NVIDIA=false
275+
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
276+
HAS_NVIDIA=true
277+
fi
278+
279+
if [ "$HAS_RENDER_NODE" = "true" ] && [ "$HAS_NVIDIA" = "false" ]; then
280+
cat > "$KASM_USER_CFG" <<'KASMGPUCFG'
281+
# managed-by-developer-template: kasmvnc-hw3d
282+
desktop:
283+
gpu:
284+
hw3d: true
285+
drinode: /dev/dri/renderD128
286+
KASMGPUCFG
287+
elif [ "$HAS_NVIDIA" = "true" ]; then
288+
# NVIDIA propietario: hw3d no soporta DRI3/GBM; configurar Zink (OpenGL→Vulkan→GPU)
289+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
290+
rm -f "$KASM_USER_CFG"
291+
fi
292+
ZINK_TAG="# managed-by-developer-template: zink-nvidia"
293+
if ! grep -qF "$ZINK_TAG" "$HOME/.xsessionrc" 2>/dev/null; then
294+
printf '%s\nexport MESA_LOADER_DRIVER_OVERRIDE=zink\nexport GALLIUM_DRIVER=zink\n' \
295+
"$ZINK_TAG" >> "$HOME/.xsessionrc"
296+
fi
297+
else
298+
# Sin render node accesible: limpiar config gestionada
299+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
300+
rm -f "$KASM_USER_CFG"
301+
fi
302+
fi
254303
fi
255304
256305
# Asegurar permisos de pipx para el usuario actual

workspaces/DeveloperAndroid/main.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,16 @@ PULSECFG
201201
if ! pgrep -u "$USER" pulseaudio >/dev/null 2>&1; then
202202
pulseaudio --start --exit-idle-time=-1 || true
203203
fi
204+
# Cargar null-sink virtual para que KasmVNC pueda capturar audio
205+
# (en contenedores Docker no hay hardware de audio; el null-sink actua como sink por defecto)
206+
for _pa_try in 1 2 3; do
207+
if pactl load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable" 2>/dev/null; then
208+
pactl set-default-sink vcable 2>/dev/null || true
209+
break
210+
fi
211+
sleep 1
212+
done
213+
unset _pa_try
204214
205215
# Alinear grupos para /dev/kvm sin tocar permisos del host
206216
if [ -e /dev/kvm ]; then
@@ -240,6 +250,45 @@ PULSECFG
240250
fi
241251
fi
242252
done
253+
254+
# Activar aceleracion 3D en KasmVNC solo cuando la ruta GBM/DRI es viable.
255+
# Nota: con driver NVIDIA propietario suele fallar con "Failed to create gbm".
256+
mkdir -p "$HOME/.vnc"
257+
KASM_USER_CFG="$HOME/.vnc/kasmvnc.yaml"
258+
KASM_MANAGED_TAG="# managed-by-developerandroid-template: kasmvnc-hw3d"
259+
HAS_RENDER_NODE=false
260+
if [ -e /dev/dri/renderD128 ] && [ -r /dev/dri/renderD128 ] && [ -w /dev/dri/renderD128 ]; then
261+
HAS_RENDER_NODE=true
262+
fi
263+
HAS_NVIDIA=false
264+
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
265+
HAS_NVIDIA=true
266+
fi
267+
268+
if [ "$HAS_RENDER_NODE" = "true" ] && [ "$HAS_NVIDIA" = "false" ]; then
269+
cat > "$KASM_USER_CFG" <<'KASMGPUCFG'
270+
# managed-by-developerandroid-template: kasmvnc-hw3d
271+
desktop:
272+
gpu:
273+
hw3d: true
274+
drinode: /dev/dri/renderD128
275+
KASMGPUCFG
276+
elif [ "$HAS_NVIDIA" = "true" ]; then
277+
# NVIDIA propietario: hw3d no soporta DRI3/GBM; configurar Zink (OpenGL→Vulkan→GPU)
278+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
279+
rm -f "$KASM_USER_CFG"
280+
fi
281+
ZINK_TAG="# managed-by-developerandroid-template: zink-nvidia"
282+
if ! grep -qF "$ZINK_TAG" "$HOME/.xsessionrc" 2>/dev/null; then
283+
printf '%s\nexport MESA_LOADER_DRIVER_OVERRIDE=zink\nexport GALLIUM_DRIVER=zink\n' \
284+
"$ZINK_TAG" >> "$HOME/.xsessionrc"
285+
fi
286+
else
287+
# Sin render node accesible: limpiar config gestionada
288+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
289+
rm -f "$KASM_USER_CFG"
290+
fi
291+
fi
243292
fi
244293
245294
# Asegurar /home/coder como HOME efectivo incluso si se ejecuta como root

workspaces/Maker/main.tf

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,16 @@ PULSECFG
217217
if ! pgrep -u "$USER" pulseaudio >/dev/null 2>&1; then
218218
pulseaudio --start --exit-idle-time=-1 || true
219219
fi
220+
# Cargar null-sink virtual para que KasmVNC pueda capturar audio
221+
# (en contenedores Docker no hay hardware de audio; el null-sink actua como sink por defecto)
222+
for _pa_try in 1 2 3; do
223+
if pactl load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable" 2>/dev/null; then
224+
pactl set-default-sink vcable 2>/dev/null || true
225+
break
226+
fi
227+
sleep 1
228+
done
229+
unset _pa_try
220230
221231
if [ "${tostring(local.enable_dri)}" = "true" ]; then
222232
# Alinear grupos para /dev/dri (rendering GPU) sin tocar permisos del host
@@ -261,9 +271,18 @@ desktop:
261271
hw3d: true
262272
drinode: /dev/dri/renderD128
263273
KASMGPUCFG
274+
elif [ "$HAS_NVIDIA" = "true" ]; then
275+
# NVIDIA propietario: hw3d no soporta DRI3/GBM; configurar Zink (OpenGL→Vulkan→GPU)
276+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
277+
rm -f "$KASM_USER_CFG"
278+
fi
279+
ZINK_TAG="# managed-by-maker-template: zink-nvidia"
280+
if ! grep -qF "$ZINK_TAG" "$HOME/.xsessionrc" 2>/dev/null; then
281+
printf '%s\nexport MESA_LOADER_DRIVER_OVERRIDE=zink\nexport GALLIUM_DRIVER=zink\n' \
282+
"$ZINK_TAG" >> "$HOME/.xsessionrc"
283+
fi
264284
else
265-
# Si existe un fichero gestionado por este template, retirarlo para evitar
266-
# que KasmVNC no arranque en hosts sin soporte GBM/DRI compatible.
285+
# Sin render node accesible: limpiar config gestionada
267286
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
268287
rm -f "$KASM_USER_CFG"
269288
fi

workspaces/OpenClaw/main.tf

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,16 @@ PULSECFG
158158
if ! pgrep -u "$USER" pulseaudio >/dev/null 2>&1; then
159159
pulseaudio --start --exit-idle-time=-1 || true
160160
fi
161+
# Cargar null-sink virtual para que KasmVNC pueda capturar audio
162+
# (en contenedores Docker no hay hardware de audio; el null-sink actua como sink por defecto)
163+
for _pa_try in 1 2 3; do
164+
if pactl load-module module-null-sink sink_name=vcable sink_properties=device.description="VirtualCable" 2>/dev/null; then
165+
pactl set-default-sink vcable 2>/dev/null || true
166+
break
167+
fi
168+
sleep 1
169+
done
170+
unset _pa_try
161171
162172
# Asegurar /home/coder como HOME efectivo incluso si se ejecuta como root
163173
sudo mkdir -p /home/coder
@@ -183,6 +193,45 @@ PULSECFG
183193
fi
184194
fi
185195
done
196+
197+
# Activar aceleracion 3D en KasmVNC solo cuando la ruta GBM/DRI es viable.
198+
# Nota: con driver NVIDIA propietario suele fallar con "Failed to create gbm".
199+
mkdir -p "$HOME/.vnc"
200+
KASM_USER_CFG="$HOME/.vnc/kasmvnc.yaml"
201+
KASM_MANAGED_TAG="# managed-by-openclaw-template: kasmvnc-hw3d"
202+
HAS_RENDER_NODE=false
203+
if [ -e /dev/dri/renderD128 ] && [ -r /dev/dri/renderD128 ] && [ -w /dev/dri/renderD128 ]; then
204+
HAS_RENDER_NODE=true
205+
fi
206+
HAS_NVIDIA=false
207+
if command -v nvidia-smi >/dev/null 2>&1 && nvidia-smi >/dev/null 2>&1; then
208+
HAS_NVIDIA=true
209+
fi
210+
211+
if [ "$HAS_RENDER_NODE" = "true" ] && [ "$HAS_NVIDIA" = "false" ]; then
212+
cat > "$KASM_USER_CFG" <<'KASMGPUCFG'
213+
# managed-by-openclaw-template: kasmvnc-hw3d
214+
desktop:
215+
gpu:
216+
hw3d: true
217+
drinode: /dev/dri/renderD128
218+
KASMGPUCFG
219+
elif [ "$HAS_NVIDIA" = "true" ]; then
220+
# NVIDIA propietario: hw3d no soporta DRI3/GBM; configurar Zink (OpenGL→Vulkan→GPU)
221+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
222+
rm -f "$KASM_USER_CFG"
223+
fi
224+
ZINK_TAG="# managed-by-openclaw-template: zink-nvidia"
225+
if ! grep -qF "$ZINK_TAG" "$HOME/.xsessionrc" 2>/dev/null; then
226+
printf '%s\nexport MESA_LOADER_DRIVER_OVERRIDE=zink\nexport GALLIUM_DRIVER=zink\n' \
227+
"$ZINK_TAG" >> "$HOME/.xsessionrc"
228+
fi
229+
else
230+
# Sin render node accesible: limpiar config gestionada
231+
if [ -f "$KASM_USER_CFG" ] && grep -qF "$KASM_MANAGED_TAG" "$KASM_USER_CFG"; then
232+
rm -f "$KASM_USER_CFG"
233+
fi
234+
fi
186235
fi
187236
188237
# Configurar PATH para .local/bin (siempre útil)

0 commit comments

Comments
 (0)