Parcourir la source

Support RandR (including fullscreen and SDL), DBus, Wine, and many other features

ehfd il y a 4 ans
Parent
commit
1fbae346a2
5 fichiers modifiés avec 77 ajouts et 83 suppressions
  1. 20 19
      Dockerfile
  2. 10 25
      README.md
  3. 38 34
      bootstrap.sh
  4. 1 3
      supervisord.conf
  5. 8 2
      xgl.yaml

+ 20 - 19
Dockerfile

@@ -1,4 +1,4 @@
-FROM nvidia/opengl:1.2-glvnd-devel-ubuntu20.04
+FROM nvidia/opengl:1.2-glvnd-runtime-ubuntu20.04
 
 LABEL maintainer "https://github.com/ehfd"
 
@@ -13,6 +13,7 @@ ENV VNCPASS vncpasswd
 ENV SIZEW 1920
 ENV SIZEH 1080
 ENV CDEPTH 24
+ENV VIDEO_PORT DFP
 
 # Install locales to prevent errors
 RUN apt-get clean && \
@@ -39,7 +40,7 @@ RUN dpkg --add-architecture i386 && \
         pkg-config && \
     rm -rf /var/lib/apt/lists/*
 
-# Install Xorg and desktop packages
+# Install Xorg, MATE desktop, and others
 RUN apt-get update && apt-get install -y \
         software-properties-common \
         wget \
@@ -59,6 +60,8 @@ RUN apt-get update && apt-get install -y \
         python-numpy \
         python3 \
         python3-numpy \
+        dbus-x11 \
+        libdbus-c++-1-0v5 \
         x11-xkb-utils \
         x11-xserver-utils \
         xauth \
@@ -82,9 +85,11 @@ RUN apt-get update && apt-get install -y \
         mesa-utils \
         x11vnc \
         x11-apps && \
+    # Remove Bluetooth packages that throw errors
+    apt-get autoremove --purge -y blueman bluez bluez-cups pulseaudio-module-bluetooth && \
     rm -rf /var/lib/apt/lists/*
 
-# Install Vulkan
+# Install Vulkan and fix containerization issues
 RUN apt-get update && apt-get install -y --no-install-recommends \
         libvulkan-dev \
         vulkan-validationlayers-dev \
@@ -98,13 +103,15 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
     meson install -C builddir && \
     rm -rf /tmp/*
 
-# Sound driver including PulseAudio and GTK library
-# If you want to use sounds on docker, try 'pulseaudio --start'
-RUN apt-get update && apt-get install -y --no-install-recommends \
-        alsa \
-        pulseaudio \
-        libgtk2.0-0 && \
-    rm -rf /var/lib/apt/lists/*
+# Wine and Winetricks, comment out the below lines to disable
+ARG WINE_BRANCH=stable
+RUN curl -fsSL https://dl.winehq.org/wine-builds/winehq.key | APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=1 apt-key add - && \
+    apt-add-repository "deb https://dl.winehq.org/wine-builds/ubuntu/ $(grep VERSION_CODENAME= /etc/os-release | cut -d= -f2) main" && \
+    apt-get update && apt-get install -y --install-recommends winehq-${WINE_BRANCH} && \
+    rm -rf /var/lib/apt/lists/* && \
+    curl -fsSL -o /usr/bin/winetricks https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks && \
+    chmod 755 /usr/bin/winetricks && \
+    curl -fsSL -o /usr/share/bash-completion/completions/winetricks https://raw.githubusercontent.com/Winetricks/winetricks/master/src/winetricks.bash-completion
 
 # noVNC and Websockify
 ENV NOVNC_VERSION 1.2.0
@@ -113,25 +120,19 @@ RUN curl -fsSL https://github.com/novnc/noVNC/archive/v${NOVNC_VERSION}.tar.gz |
     ln -s /opt/noVNC/vnc.html /opt/noVNC/index.html && \
     git clone https://github.com/novnc/websockify /opt/noVNC/utils/websockify
 
-# Xorg segfault error mitigation
-RUN apt-get update && apt-get install -y --no-install-recommends \
-        dbus-x11 \
-        libdbus-c++-1-0v5 && \
-    rm -rf /var/lib/apt/lists/*
-
 # Create user with password ${VNCPASS}
 RUN apt-get update && apt-get install -y --no-install-recommends \
         sudo && \
     rm -rf /var/lib/apt/lists/* && \
     groupadd -g 1000 user && \
     useradd -ms /bin/bash user -u 1000 -g 1000 && \
-    usermod -a -G adm,audio,cdrom,dialout,dip,fax,floppy,input,lpadmin,netdev,plugdev,render,scanner,ssh,sudo,tape,tty,video,voice user && \
+    usermod -a -G adm,audio,cdrom,dialout,dip,fax,floppy,input,lp,lpadmin,netdev,plugdev,render,scanner,ssh,sudo,tape,tty,video,voice user && \
     echo "user ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
     chown -R user:user /home/user && \
     echo "user:${VNCPASS}" | chpasswd
 
-COPY bootstrap.sh /bootstrap.sh
-RUN chmod 755 /bootstrap.sh
+COPY bootstrap.sh /etc/bootstrap.sh
+RUN chmod 755 /etc/bootstrap.sh
 COPY supervisord.conf /etc/supervisord.conf
 RUN chmod 755 /etc/supervisord.conf
 

+ 10 - 25
README.md

@@ -1,36 +1,21 @@
 # docker-nvidia-glx-desktop
 
-MATE Desktop container supporting GLX/Vulkan for NVIDIA GPUs by spawning its own
-X Server and noVNC WebSocket interface instead of using the host X server. Does
-not require `/tmp/.X11-unix` host sockets or host configuration.
+MATE Desktop container supporting GLX/Vulkan for NVIDIA GPUs by spawning its own X Server and noVNC WebSocket interface instead of using the host X server. Does not require `/tmp/.X11-unix` host sockets or host configuration. Designed for Kubernetes.
 
-Use
-[docker-nvidia-egl-desktop](https://github.com/ehfd/docker-nvidia-egl-desktop)
-for a MATE Desktop container that directly accesses NVIDIA GPUs without using an
-X Server or privileged mode and is compatible with Kubernetes (without Vulkan
-support).
+Use [docker-nvidia-egl-desktop](https://github.com/ehfd/docker-nvidia-egl-desktop) for a MATE Desktop container that directly accesses NVIDIA GPUs without using an X11 Server, and is also compatible with Kubernetes (but without Vulkan support unlike this container).
 
-Corresponding container toolkit on the host for allocating GPUs should be set
-up. Container startup should take some time as it automatically installs NVIDIA
-drivers.
+Requires reasonably recent NVIDIA GPU drivers and corresponding container toolkits to be set up on the host for allocating GPUs. GPUs should have one or more DVI/HDMI/DisplayPort digital video ports instead of having only analog video ports (very ancient GPUs), although the ports to be used are recommended NOT to be connected with an actual monitor. Since this container fakes the driver to simulate being plugged in to a monitor while it actually does not, make sure the resolutions specified with the environment variables **SIZEW** and **SIZEH** are within the maximum supported by the GPU (1920 x 1200 at 60 hz is the maximum that should work on default configuration without DisplayPort for any recent enough GPUs, and the sizes between this and the GPU maximum size will be functional if the port is set to DisplayPort). The environment variable **VIDEO_PORT** can override which video port is used (defaults to DFP, the first unoccupied port detected in the driver), and overriding **VIDEO_PORT** to an unplugged DisplayPort (for example numbered like DP-0, DP-1, and so on) is recommended for resolutions above 1920 x 1200, because of some driver restrictions applied when the default is a DVI or HDMI port. If all your GPUs are not connected to any monitors and have DisplayPort, simply setting **VIDEO_PORT** to DP-0 is recommended (but not set as default because of legacy compatibility reasons).
 
-Connect to the spawned noVNC WebSocket instance with a browser in port 5901, no
-VNC client required (password for the default user is 'vncpasswd').
+Container startup could take some time at first startup as it automatically installs NVIDIA drivers with the same version as the host.
 
-This configuration allows usage of multiple GPU desktops per node but the
-container will use potentially unsafe privileged mode:
+Connect to the spawned noVNC WebSocket instance with a browser in port 5901, no VNC client required (password for the default user is 'vncpasswd').
 
-```
-docker run --gpus 1 --privileged -it -e SIZEW=1920 -e SIZEH=1080 -e SHARED=TRUE -e VNCPASS=vncpasswd -p 5901:5901 ehfd/nvidia-glx-desktop:latest
-```
+Wine and Winetricks are bundled by default, comment out the installation section in **Dockerfile** if the user wants to remove them from the container.
 
-Without privileged mode only one GPU desktop can be used per node because of
-Xorg limitations:
-
-Note: Requires **/dev/ttyN** (N >= 8) provision. Check out
-[k8s-hostdev-plugin](https://github.com/bluebeach/k8s-hostdev-plugin) for
-provisioning this in Kubernetes clusters without privileged access.
+This container should not be used in privileged mode, and requires **/dev/ttyN** (N >= 8) virtual terminal device provisioning. All containers in a single node must be provisioned with one chosen virtual terminal device. Check out [smarter-device-manager](https://gitlab.com/arm-research/smarter/smarter-device-manager) or [k8s-hostdev-plugin](https://github.com/bluebeach/k8s-hostdev-plugin) for provisioning this in Kubernetes clusters without privileged access.
 
 ```
-docker run --gpus 1 --device=/dev/tty63:rw -it -e SIZEW=1920 -e SIZEH=1080 -e SHARED=TRUE -e VNCPASS=vncpasswd -p 5901:5901 ehfd/nvidia-glx-desktop:latest
+docker run --gpus 1 --device=/dev/tty63:rw -it -e SIZEW=1920 -e SIZEH=1080 -e SHARED=TRUE -e VNCPASS=vncpasswd -e VIDEO_PORT=DFP -p 5901:5901 ehfd/nvidia-glx-desktop:latest
 ```
+
+This work was supported in part by NSF awards CNS-1730158, ACI-1540112, ACI-1541349, OAC-1826967, the University of California Office of the President, and the University of California San Diego’s California Institute for Telecommunications and Information Technology/Qualcomm Institute. Thanks to CENIC for the 100Gbps networks.

+ 38 - 34
bootstrap.sh

@@ -1,32 +1,38 @@
 #!/bin/bash
-
-# Install NVIDIA drivers, including X graphic drivers by omitting --x-{prefix,module-path,library-path,sysconfig-path}
-export DRIVER_VERSION=$(head -n1 </proc/driver/nvidia/version | awk '{ print $8 }')
-BASE_URL=https://us.download.nvidia.com/XFree86/Linux-x86_64
-cd /tmp
-curl -fSsl -O $BASE_URL/$DRIVER_VERSION/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run
-sudo sh NVIDIA-Linux-x86_64-$DRIVER_VERSION.run -x
-cd NVIDIA-Linux-x86_64-$DRIVER_VERSION
-sudo ./nvidia-installer --silent \
-                   --no-kernel-module \
-                   --install-compat32-libs \
-                   --no-nouveau-check \
-                   --no-nvidia-modprobe \
-                   --no-rpms \
-                   --no-backup \
-                   --no-check-for-alternate-installs \
-                   --no-libglx-indirect \
-                   --no-install-libglvnd
-sudo rm -rf /tmp/NVIDIA*
-cd ~
-
 set -e
 
 trap "echo TRAPed signal" HUP INT QUIT KILL TERM
 
 echo "user:$VNCPASS" | sudo chpasswd
 
-sudo sed -i "s/allowed_users=console/allowed_users=anybody/;$ a needs_root_rights=yes" /etc/X11/Xwrapper.config
+sudo /etc/init.d/dbus start
+
+# Install NVIDIA drivers, including X graphic drivers by omitting --x-{prefix,module-path,library-path,sysconfig-path}
+if ! command -v nvidia-xconfig &> /dev/null; then
+  export DRIVER_VERSION=$(head -n1 </proc/driver/nvidia/version | awk '{print $8}')
+  BASE_URL=https://download.nvidia.com/XFree86/Linux-x86_64
+  cd /tmp
+  curl -fsSL -O $BASE_URL/$DRIVER_VERSION/NVIDIA-Linux-x86_64-$DRIVER_VERSION.run
+  sudo sh NVIDIA-Linux-x86_64-$DRIVER_VERSION.run -x
+  cd NVIDIA-Linux-x86_64-$DRIVER_VERSION
+  sudo ./nvidia-installer --silent \
+                    --no-kernel-module \
+                    --install-compat32-libs \
+                    --no-nouveau-check \
+                    --no-nvidia-modprobe \
+                    --no-rpms \
+                    --no-backup \
+                    --no-check-for-alternate-installs \
+                    --no-libglx-indirect \
+                    --no-install-libglvnd
+  sudo rm -rf /tmp/NVIDIA*
+  sudo sed -i "s/allowed_users=console/allowed_users=anybody/;$ a needs_root_rights=yes" /etc/X11/Xwrapper.config
+  cd ~
+fi
+
+if [ -f "/etc/X11/xorg.conf" ]; then
+  sudo rm /etc/X11/xorg.conf
+fi
 
 if [ "$NVIDIA_VISIBLE_DEVICES" == "all" ]; then
   export GPU_SELECT=$(sudo nvidia-smi --query-gpu=uuid --format=csv | sed -n 2p)
@@ -44,30 +50,29 @@ if [ -z "$GPU_SELECT" ]; then
   exit 1
 fi
 
-if ! sudo nvidia-smi --id="$GPU_SELECT" -q | grep -q "Tesla"; then
-  DISPLAYSTRING="--use-display-device=None"
-fi
-
 HEX_ID=$(sudo nvidia-smi --query-gpu=pci.bus_id --id="$GPU_SELECT" --format=csv | sed -n 2p)
 IFS=":." ARR_ID=($HEX_ID)
 unset IFS
 BUS_ID=PCI:$((16#${ARR_ID[1]})):$((16#${ARR_ID[2]})):$((16#${ARR_ID[3]}))
-sudo nvidia-xconfig --virtual="${SIZEW}x${SIZEH}" --depth="$CDEPTH" --mode="${SIZEW}x${SIZEH}" --allow-empty-initial-configuration --no-use-edid-dpi --busid="$BUS_ID" --only-one-x-screen --no-xinerama "$DISPLAYSTRING"
-
-if [ "x$SHARED" == "xTRUE" ]; then
-  export SHARESTRING="-shared"
-fi
+export MODELINE=$(cvt -r ${SIZEW} ${SIZEH} | sed -n 2p)
+sudo nvidia-xconfig --virtual="${SIZEW}x${SIZEH}" --depth="$CDEPTH" --mode=$(echo $MODELINE | awk '{print $2}' | tr -d '"') --allow-empty-initial-configuration --no-probe-all-gpus --busid="$BUS_ID" --only-one-x-screen --connected-monitor="$VIDEO_PORT"
+sudo sed -i '/Driver\s\+"nvidia"/a\    Option         "ModeValidation" "NoMaxPClkCheck, NoEdidMaxPClkCheck, NoMaxSizeCheck, NoHorizSyncCheck, NoVertRefreshCheck, NoVirtualSizeCheck, NoExtendedGpuCapabilitiesCheck, NoTotalSizeCheck, NoDualLinkDVICheck, NoDisplayPortBandwidthCheck, AllowNon3DVisionModes, AllowNonHDMI3DModes, AllowNonEdidModes, NoEdidHDMI2Check, AllowDpInterlaced"\n    Option         "DPI" "96 x 96"' /etc/X11/xorg.conf
+sudo sed -i '/Section\s\+"Monitor"/a\    '"$MODELINE" /etc/X11/xorg.conf
 
 shopt -s extglob
 for TTY in $(ls -1 /dev/tty+([0-9]) | sort -rV); do
   if [ -w "$TTY" ]; then
-    Xorg vt"$(echo "$TTY" | grep -Eo '[0-9]+$')" :0 &
+    Xorg vt"$(echo "$TTY" | grep -Eo '[0-9]+$')" -sharevts :0 &
     break
   fi
 done
 sleep 1
 
-x11vnc -display :0 -passwd "$VNCPASS" -forever -repeat -xkb -xrandr resize -noxinerama -rfbport 5900 "$SHARESTRING" &
+if [ "x$SHARED" == "xTRUE" ]; then
+  export SHARESTRING="-shared"
+fi
+
+x11vnc -display ":0" -passwd "$VNCPASS" -forever -repeat -xkb -xrandr "resize" -rfbport 5900 "$SHARESTRING" &
 sleep 1
 
 /opt/noVNC/utils/launch.sh --vnc localhost:5900 --listen 5901 &
@@ -90,7 +95,6 @@ else
 fi
 
 mate-session &
-
 pulseaudio --start
 
 echo "Session Running. Press [Return] to exit."

+ 1 - 3
supervisord.conf

@@ -6,11 +6,9 @@ logfile=/tmp/supervisord.log
 pidfile=/tmp/supervisord.pid
 
 [program:bootstrap]
-user=user
-command=/bootstrap.sh
+command=/etc/bootstrap.sh
 logfile=/tmp/bootstrap.log
 pidfile=/tmp/bootstrap.pid
-process_name=%(program_name)s
 stopsignal=INT
 autostart=true
 autorestart=true

+ 8 - 2
xgl.yaml

@@ -29,12 +29,12 @@ spec:
           value: "TRUE"
         - name: VNCPASS
           value: "vncpasswd"
+        - name: VIDEO_PORT
+          value: "DFP"
 #          valueFrom:
 #            secretKeyRef:
 #              name: xgl-pass
 #              key: xgl-pass
-        securityContext:
-          privileged: true
         stdin: true
         tty: true
         ports:
@@ -55,6 +55,8 @@ spec:
           name: xgl-root-vol
         - mountPath: /dev/shm
           name: dshm
+        - mountPath: /dev/tty63
+          name: tty
       volumes:
       - name: xgl-cache-vol
         emptyDir: {}
@@ -67,3 +69,7 @@ spec:
       - name: dshm
         emptyDir:
           medium: Memory
+# Replace this with the cluster's device plugin entry that provisions the virtual terminal device
+      - name: tty
+        hostPath:
+          path: /dev/tty63