Skip to content

Commit

Permalink
Implement VNC GuiVM
Browse files Browse the repository at this point in the history
We expose a new 'guivm' flavor. In order to enable this remote GuiVM,
one has to enable Qubes services:

- lightdm
- guivm
- guivm-vnc

This is similar to `sys-gui-gpu` setup but here, `guivm-vnc` service
add ExecStartPre and ExecStartPost to lightdm systemd service in order
to configure Xorg server with dummyqbs driver and x11vnc server.
  • Loading branch information
fepitre committed Jun 22, 2021
1 parent e201e39 commit eab7854
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 11 deletions.
20 changes: 14 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,7 @@ clean:

install: install-rh-agent install-pulseaudio

install-rh-agent: appvm install-common
install -m 0644 -D appvm-scripts/qubes-gui-agent.service \
$(DESTDIR)/$(SYSLIBDIR)/systemd/system/qubes-gui-agent.service
install-rh-agent: appvm install-common install-systemd
install -m 0644 -D appvm-scripts/etc/sysconfig/desktop \
$(DESTDIR)/etc/sysconfig/desktop
install -D appvm-scripts/etc/X11/xinit/xinitrc.d/20qt-x11-no-mitshm.sh \
Expand All @@ -91,13 +89,11 @@ install-rh-agent: appvm install-common
install -D appvm-scripts/etc/X11/xinit/xinitrc.d/60xfce-desktop.sh \
$(DESTDIR)/etc/X11/xinit/xinitrc.d/60xfce-desktop.sh

install-debian: appvm install-common install-pulseaudio
install-debian: appvm install-common install-pulseaudio install-systemd
install -d $(DESTDIR)/etc/X11/Xsession.d
install -m 0644 appvm-scripts/etc/X11/Xsession.d/* $(DESTDIR)/etc/X11/Xsession.d/
install -d $(DESTDIR)/etc/xdg
install -m 0644 appvm-scripts/etc/xdg-debian/* $(DESTDIR)/etc/xdg
install -m 0644 -D appvm-scripts/qubes-gui-agent.service \
$(DESTDIR)/$(SYSLIBDIR)/systemd/system/qubes-gui-agent.service

install-pulseaudio:
install -D pulse/start-pulseaudio-with-vchan \
Expand All @@ -116,6 +112,10 @@ endif
install -m 0644 -D appvm-scripts/etc/xdgautostart/qubes-pulseaudio.desktop \
$(DESTDIR)/etc/xdg/autostart/qubes-pulseaudio.desktop

install-systemd:
install -m 0644 -D appvm-scripts/qubes-gui-agent.service \
$(DESTDIR)/$(SYSLIBDIR)/systemd/system/qubes-gui-agent.service

install-common:
install -D gui-agent/qubes-gui $(DESTDIR)/usr/bin/qubes-gui
install -D gui-common/qubes-gui-runuser $(DESTDIR)/usr/bin/qubes-gui-runuser
Expand All @@ -130,6 +130,10 @@ install-common:
$(DESTDIR)/usr/bin/qubes-run-xephyr
install -D appvm-scripts/usrbin/qubes-start-xephyr \
$(DESTDIR)/usr/bin/qubes-start-xephyr
install -D appvm-scripts/usrbin/qubes-run-x11vnc-pre \
$(DESTDIR)/usr/bin/qubes-run-x11vnc-pre
install -D appvm-scripts/usrbin/qubes-run-x11vnc \
$(DESTDIR)/usr/bin/qubes-run-x11vnc
install -D appvm-scripts/usrbin/qubes-change-keyboard-layout \
$(DESTDIR)/usr/bin/qubes-change-keyboard-layout
install -D appvm-scripts/usrbin/qubes-set-monitor-layout \
Expand All @@ -142,6 +146,10 @@ install-common:
$(DESTDIR)$(LIBDIR)/xorg/modules/drivers/dummyqbs_drv.so
install -m 0644 -D appvm-scripts/etc/X11/xorg-qubes.conf.template \
$(DESTDIR)/etc/X11/xorg-qubes.conf.template
install -m 0644 -D appvm-scripts/etc/X11/xorg-qubes-x11vnc.conf.template \
$(DESTDIR)/etc/X11/xorg-qubes-x11vnc.conf.template
install -m 0644 -D appvm-scripts/etc/systemd/system/lightdm.service.d/qubes-guivm-vnc.conf \
$(DESTDIR)/etc/systemd/system/lightdm.service.d/qubes-guivm-vnc.conf
install -m 0644 -D appvm-scripts/etc/profile.d/qubes-gui.sh \
$(DESTDIR)/etc/profile.d/qubes-gui.sh
install -m 0644 -D appvm-scripts/etc/profile.d/qubes-gui.csh \
Expand Down
4 changes: 2 additions & 2 deletions appvm-scripts/etc/X11/Xsession.d/50guivm-windows-prefix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
QUBES_VMNAME="$(qubesdb-read /guivm-windows-prefix)"

# Set _QUBES_VMNAME atom for a window manager (e.g. xfwm4)
if qsvc guivm-gui-agent; then
if qsvc guivm; then
xprop -root -f _QUBES_VMNAME 8s -set _QUBES_VMNAME "${QUBES_VMNAME:-GuiVM}"
fi
fi
4 changes: 2 additions & 2 deletions appvm-scripts/etc/X11/Xsession.d/60xfce-desktop
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# shellcheck disable=SC1091
. /usr/lib/qubes/init/functions

if ! qsvc guivm-gui-agent; then
if ! qsvc guivm; then

XDG_MENU_PREFIX="xfce-"
export XDG_MENU_PREFIX
Expand All @@ -27,4 +27,4 @@ fi
export QT_QPA_PLATFORMTHEME=qt5ct

xfsettingsd --replace&
fi
fi
34 changes: 34 additions & 0 deletions appvm-scripts/etc/X11/xorg-qubes-x11vnc.conf.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
Section "Module"
Load "fb"
EndSection

Section "ServerLayout"
Identifier "Default Layout"
Screen 0 "Screen0" 0 0
EndSection

Section "Device"
Identifier "Videocard0"
Driver "dummyqbs"
VideoRam %MEM%
Option "GUIDomID" "%GUI_DOMID%"
EndSection

Section "Monitor"
Identifier "Monitor0"
HorizSync %MIN_MAX_HSYNC%
VertRefresh %MIN_MAX_VSYNC%
%MODELINES%
Option "PreferredMode" "QB1024x768"
EndSection

Section "Screen"
Identifier "Screen0"
Device "Videocard0"
Monitor "Monitor0"
DefaultDepth %DEPTH%
SubSection "Display"
Viewport 0 0
Depth %DEPTH%
EndSubSection
EndSection
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[Unit]
ConditionPathExists=/var/run/qubes-service/lightdm

[Service]
ExecStartPre=/usr/bin/qubes-run-x11vnc-pre
ExecStartPost=/usr/bin/qubes-run-x11vnc
26 changes: 26 additions & 0 deletions appvm-scripts/usrbin/qubes-run-x11vnc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/sh
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2021 Frédéric Pierret <[email protected]>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#
X11VNC=/usr/bin/x11vnc
# WIP: Ensure to have the good set of x11vnc options.
OPTIONS_VNC="-display :0 -auth /var/run/lightdm/root/\:0 -noxrecord -noxfixes -noxdamage -loop"

$X11VNC $OPTIONS_VNC &
112 changes: 112 additions & 0 deletions appvm-scripts/usrbin/qubes-run-x11vnc-pre
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/bin/bash
#
# The Qubes OS Project, http://www.qubes-os.org
#
# Copyright (C) 2021 Frédéric Pierret <[email protected]>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
#

# Source Qubes library.
# shellcheck disable=SC1091
. /usr/lib/qubes/init/functions

array_min_max() {
read -r -a array <<< "$@"
max=${array[0]}
min=${array[0]}

for i in ${array[*]}; do
(( i > max )) && max=$i
(( i < min )) && min=$i
done
echo "$min"-"$max"
}

if qsvc guivm-vnc; then
GUI_DOMID="$(qubesdb-read /qubes-gui-domain-xid 2>/dev/null)"
MEM_MIN="$(qubesdb-read /qubes-gui-videoram-min 2>/dev/null)"
MEM_OVERHEAD="$(qubesdb-read /qubes-gui-videoram-overhead 2>/dev/null)"
: "${MEM_MIN:=0}"
: "${MEM_OVERHEAD:=$((2560 * 1600 * 4 / 1024))}"

MEM=$((MEM + MEM_OVERHEAD))
if [ $MEM -lt $MEM_MIN ]; then
MEM=$MEM_MIN
fi

DUMMY_MAX_CLOCK=300
PREFERRED_HSYNC=50
DEPTH=24

HSYNC=()
VSYNC=()
MODELINES=()
RESOLUTIONS="320x240
640x480
800x600
1024x768
1152x864
1280x1024
1400x1050
1600x1200
2048x1536
800x480
1366x768
1440x900
1600x1024
1680x1050
1920x1200
2560x1600
1280x720
1920x1080"

for RES in ${RESOLUTIONS[*]};
do
W=${RES%x*}
H=${RES#*x}
HTOTAL=$((W+3))
VTOTAL=$((H+3))
CLOCK=$((PREFERRED_HSYNC*HTOTAL/1000))
if [ $CLOCK -gt $DUMMY_MAX_CLOCK ]; then CLOCK=$DUMMY_MAX_CLOCK ; fi
MODELINE="$CLOCK $W $((W+1)) $((W+2)) $HTOTAL $H $((H+1)) $((H+2)) $VTOTAL"

HSYNC_START=$((CLOCK*1000/HTOTAL))
HSYNC_END=$((HSYNC_START+1))

VREFR_START=$((CLOCK*1000000/HTOTAL/VTOTAL))
VREFR_END=$((VREFR_START+1))

HSYNC+=("$HSYNC_START" "$HSYNC_END")
VSYNC+=("$VREFR_START" "$VREFR_END")
MODELINES+=(" Modeline \"QB$RES\" $MODELINE")
done

ALL_MODELINES="$(printf '%s\\n' "${MODELINES[@]}")"
MIN_MAX_HSYNC="$(array_min_max "${HSYNC[@]}")"
MIN_MAX_VSYNC="$(array_min_max "${VSYNC[@]}")"

sed -e s/%MEM%/$MEM/ \
-e s/%GUI_DOMID%/"$GUI_DOMID"/ \
-e s/%DEPTH%/$DEPTH/ \
-e s/%MODELINES%/"$ALL_MODELINES"/ \
-e s/%MIN_MAX_HSYNC%/"$MIN_MAX_HSYNC"/ \
-e s/%MIN_MAX_VSYNC%/"$MIN_MAX_VSYNC"/ \
< /etc/X11/xorg-qubes-x11vnc.conf.template > /etc/X11/xorg.conf

# 2**30
echo 1073741824 > /sys/module/xen_gntalloc/parameters/limit
fi
3 changes: 2 additions & 1 deletion appvm-scripts/usrbin/qubes-run-xorg
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
# shellcheck disable=SC1091
. /usr/lib/qubes/init/functions

## This script is triggered by qubes-gui-agent systemd service.

#expects W, H, MEM and DEPTH env vars to be set by invoker
DUMMY_MAX_CLOCK=300 #hardcoded in dummy_drv
PREFERRED_HSYNC=50
Expand Down Expand Up @@ -107,7 +109,6 @@ fi

if qsvc guivm-gui-agent; then
DISPLAY_XORG=:1
DISPLAY_XEPHYR=:0

# Create Xorg. Xephyr will be started using qubes-start-xephyr later.
exec runuser -u "$DEFAULT_USER" -- /bin/sh -l -c "exec $XORG $DISPLAY_XORG -nolisten tcp vt07 -wr -config xorg-qubes.conf > ~/.xorg-errors 2>&1" &
Expand Down
9 changes: 9 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,12 @@ Depends:
${misc:Depends}
Description: XFCE desktop support for Qubes VM
XFCE desktop support for Qubes VM

Package: qubes-gui-vnc
Architecture: any
Depends:
x11vnc
${shlibs:Depends},
${misc:Depends}
Description: Remote GuiVM support using VNC
Remote GuiVM support using VNC
4 changes: 4 additions & 0 deletions debian/qubes-gui-vnc.install
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
usr/bin/qubes-run-x11vnc-pre
usr/bin/qubes-run-x11vnc
etc/X11/xorg-qubes-x11vnc.conf.template
etc/systemd/system/lightdm.service.d/qubes-guivm-vnc.conf
14 changes: 14 additions & 0 deletions rpm_spec/gui-agent.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,13 @@ Summary: XFCE desktop support for Qubes VM
%description xfce
XFCE desktop support for Qubes VM

%package -n qubes-gui-vnc
Summary: Remote GuiVM support using VNC
Requires: x11vnc

%description -n qubes-gui-vnc
Remote GuiVM support using VNC

%description
The Qubes GUI agent that needs to be installed in VM in order to provide the
Qubes fancy GUI.
Expand Down Expand Up @@ -198,5 +205,12 @@ rm -f %{name}-%{version}
%files xfce
/etc/X11/xinit/xinitrc.d/60xfce-desktop.sh

%files -n qubes-gui-vnc
#/lib/systemd/system/qubes-gui-vncserver.service
%attr(0644,root,root) /etc/X11/xorg-qubes-x11vnc.conf.template
%attr(0644,root,root) /etc/systemd/system/lightdm.service.d/qubes-guivm-vnc.conf
/usr/bin/qubes-run-x11vnc-pre
/usr/bin/qubes-run-x11vnc

%changelog
@CHANGELOG@

0 comments on commit eab7854

Please sign in to comment.