Skip to content

Instantly share code, notes, and snippets.

@tarruda
Created July 29, 2022 01:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tarruda/b6886fc7be3c21f2f878ea74e0ea7891 to your computer and use it in GitHub Desktop.
Save tarruda/b6886fc7be3c21f2f878ea74e0ea7891 to your computer and use it in GitHub Desktop.
Debian Mate Xspice desktop
#!/bin/bash
XSERVER_DISPLAY_NUMBER=15
set -eu -o pipefail
new_image_name=debian-mate-desktop-xspice
if lxc image info local:$new_image_name &> /dev/null; then
echo "Image already exists" >&2
exit 1
fi
BASE_IMAGE_NAME=images:debian/bullseye
USERNAME=debian
GECOS="Debian User"
initial_dir=$(pwd)
tmpdir=$(mktemp -d /tmp/imgbuildXXXXXXX)
echo $tmpdir
cd $tmpdir
instance_name=$(basename $tmpdir)
cleanup() {
cd $initial_dir
rm -rfv $tmpdir
lxc stop $instance_name &> /dev/null || true
lxc delete $instance_name
}
trap cleanup EXIT TERM INT
if [ ! -x spice-vdagent ] && [ ! -x spiceqxl_drv.so ]; then
rm -fv spice-vdagent spiceqxl_drv.so
# first we create an instance for building the required patched binaries
lxc launch $BASE_IMAGE_NAME $instance_name
# fix a bug in spice-vdagentd where it doesn't recognize messages for resizing monitor
cat > f << "EOF"
diff --git a/src/vdagentd/vdagentd.c b/src/vdagentd/vdagentd.c
index 3e59331..1a16968 100644
--- a/src/vdagentd/vdagentd.c
+++ b/src/vdagentd/vdagentd.c
@@ -208,7 +208,7 @@ static void do_client_monitors(VirtioPort *vport, int port_nr,
/* Store monitor config to send to agents when they connect */
size = sizeof(VDAgentMonitorsConfig) +
new_monitors->num_of_monitors * sizeof(VDAgentMonConfig);
- if (message_header->size != size) {
+ if (message_header->size < size) {
syslog(LOG_ERR, "invalid message size for VDAgentMonitorsConfig");
return;
}
EOF
lxc file push f $instance_name/vdagent.diff
# patch xserver-xspice to support unix socket as the listen address
cat > f << "EOF"
diff --git a/src/spiceqxl_spice_server.c b/src/spiceqxl_spice_server.c
index 1a138b5..465ec48 100644
--- a/src/spiceqxl_spice_server.c
+++ b/src/spiceqxl_spice_server.c
@@ -222,7 +222,9 @@ void xspice_set_spice_server_options(OptionInfoPtr options)
}
addr_flags = 0;
- if (ipv4) {
+ if (addr && addr[0] == '/') {
+ addr_flags |= SPICE_ADDR_FLAG_UNIX_ONLY;
+ } else if (ipv4) {
addr_flags |= SPICE_ADDR_FLAG_IPV4_ONLY;
} else if (ipv6) {
addr_flags |= SPICE_ADDR_FLAG_IPV6_ONLY;
EOF
lxc file push f $instance_name/xspice.diff
# install build dependencies and setup an user to build packages
lxc exec $instance_name -- bash << EOFF
sed -n -e 'p;s/^deb\b/deb-src/p' -i /etc/apt/sources.list
export DEBIAN_FRONTEND=noninteractive
echo waiting for network configuration...
sleep 5
apt update
apt upgrade -y
apt build-dep -y spice-vdagent xserver-xspice
apt install -y fakeroot
adduser --disabled-password --gecos "$GECOS" $USERNAME
mkdir -p /output
chown 1000:1000 /output
EOFF
# patch and build packages
lxc exec $instance_name -- su $USERNAME << "EOF"
cd
apt source spice-vdagent xserver-xspice
cd spice-vdagent-*
patch -p1 < /vdagent.diff
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -b -uc -us
cp -v debian/spice-vdagent/usr/sbin/spice-vdagentd /output
cd
cd xserver-xorg-video-qxl-*
patch -p1 < /xspice.diff
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -b -uc -us
cp -v debian/xserver-xspice/usr/lib/xorg/modules/drivers/spiceqxl_drv.so /output
EOF
# copy patched binaries
lxc file pull $instance_name/output/spice-vdagentd .
lxc file pull $instance_name/output/spiceqxl_drv.so .
# delete temp image
lxc stop $instance_name
lxc delete $instance_name
fi
# create a new one where we will build the final image
lxc launch $BASE_IMAGE_NAME $instance_name
lxc exec $instance_name bash << EOFF
export DEBIAN_FRONTEND=noninteractive
echo waiting for network configuration...
sleep 5
apt update && apt upgrade -y
apt install -y bash-completion
# divert binaries that will be replaced
dpkg-divert --divert /usr/sbin/spice-vdagentd.real --rename /usr/sbin/spice-vdagentd
dpkg-divert --divert /usr/lib/xorg/modules/drivers/spiceqxl_drv.so.real --rename /usr/lib/xorg/modules/drivers/spiceqxl_drv.so
adduser --disabled-password --gecos "$GECOS" $USERNAME
usermod -aG sudo $USERNAME
passwd -de $USERNAME
# create xorg drivers directory
mkdir -pv /usr/lib/xorg/modules/drivers
EOFF
lxc file push spice-vdagentd $instance_name/usr/sbin/spice-vdagentd
lxc file push spiceqxl_drv.so $instance_name/usr/lib/xorg/modules/drivers/spiceqxl_drv.so
# Setup xspice and vdagent on the image
lxc exec $instance_name bash << EOFF
cat > /etc/tmpfiles.d/xspice.conf << "EOF"
d /run/xspice/audio 777 root root -
EOF
mkdir -pv /etc/pulse/default.pa.d
cat > /etc/pulse/default.pa.d/99-xspice.pa << "EOF"
load-module module-pipe-sink file=/run/xspice/audio/pulse.output
EOF
cat > /etc/systemd/system/spice-vdagent.path << "EOF"
[Unit]
Description=Start Spice vdagentd
[Path]
PathExists=/run/xspice/uinput
PathExists=/run/xspice/virtio
[Install]
WantedBy=graphical.target
EOF
cat > /etc/systemd/system/spice-vdagent.service << "EOF"
[Unit]
Description=Start Spice vdagentd
[Service]
ExecStart=/usr/sbin/spice-vdagentd -f -x -S /run/xspice/udcs -s /run/xspice/virtio -u /run/xspice/uinput
EOF
mkdir -pv /etc/xdg/autostart
cat > /etc/xdg/autostart/spice-vdagent-lxd.desktop << "EOF"
[Desktop Entry]
Name=Spice vdagent (LXD)
Comment=Agent for Xspice guests
Exec=/usr/bin/spice-vdagent -s /run/xspice/virtio -S /run/xspice/udcs
Terminal=false
Type=Application
X-GNOME-Autostart-Phase=WindowManager
NoDisplay=true
EOF
mkdir -pv /etc/lightdm/lightdm.conf.d
cat > /etc/lightdm/lightdm.conf.d/99-xspice.conf << "EOF"
[Seat:*]
type=xremote
greeter-hide-users=false
xserver-display-number=$XSERVER_DISPLAY_NUMBER
EOF
mkdir -pv /etc/X11
cat > /etc/X11/xspice.xorg.conf << "EOF"
Section "Device"
Identifier "XSPICE"
Driver "spiceqxl"
Option "SpiceDisableTicketing" "True"
Option "SpiceAddr" "/run/lxd-spice.unix"
Option "NumHeads" "1"
Option "EnableImageCache" "True"
Option "EnableFallbackCache" "True"
Option "EnableSurfaces" "True"
Option "SurfaceBufferSize" "128"
Option "CommandBufferSize" "128"
Option "FrameBufferSize" "16"
Option "SpiceVdagentEnabled" "True"
Option "SpiceVdagentVirtioPath" "/run/xspice/virtio"
Option "SpiceVdagentUinputPath" "/run/xspice/uinput"
Option "SpicePlaybackFIFODir" "/run/xspice/audio"
EndSection
Section "InputDevice"
Identifier "XSPICE POINTER"
Driver "xspice pointer"
EndSection
Section "InputDevice"
Identifier "XSPICE KEYBOARD"
Driver "xspice keyboard"
EndSection
Section "Monitor"
Identifier "Configured Monitor"
EndSection
Section "Screen"
Identifier "XSPICE Screen"
Monitor "Configured Monitor"
Device "XSPICE"
DefaultDepth 24
EndSection
Section "ServerLayout"
Identifier "XSPICE Example"
Screen "XSPICE Screen"
InputDevice "XSPICE KEYBOARD"
InputDevice "XSPICE POINTER"
EndSection
# Prevent udev from loading vmmouse in a vm and crashing.
Section "ServerFlags"
Option "AutoAddDevices" "False"
EndSection
EOF
cat > /etc/systemd/system/xspice.service << "EOF"
[Unit]
Description=Start Xspice
[Service]
ExecStart=/usr/lib/xorg/Xorg :$XSERVER_DISPLAY_NUMBER -config /etc/X11/xspice.xorg.conf -nolisten tcp
[Install]
WantedBy=graphical.target
EOF
cat > /etc/systemd/system/lightdm.path << "EOF"
[Unit]
Description=Start lightdm after Xorg
[Path]
PathExists=/tmp/.X11-unix/X$XSERVER_DISPLAY_NUMBER
[Install]
WantedBy=graphical.target
EOF
export DEBIAN_FRONTEND=noninteractive
apt install -y xserver-xspice spice-vdagent pulseaudio
systemctl disable lightdm.service
systemctl enable xspice.service spice-vdagent.path lightdm.path
if ! grep -q 'default\.pa\.d' < /etc/pulse/default.pa; then
cat >> /etc/pulse/default.pa <<- "EOF"
.nofail
.include /etc/pulse/default.pa.d
EOF
fi
EOFF
lxc exec $instance_name bash << "EOF"
apt install -y mate-desktop-environment mate-tweak network-manager-gnome lightdm firefox-esr
EOF
lxc stop $instance_name
lxc publish $instance_name --alias=$new_image_name
echo "Test with: \"lxc launch $new_image_name mate --console=vga\""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment