|
#!/bin/bash |
|
|
|
set -eu -o pipefail |
|
|
|
new_image_name=debian-kde-desktop-xspice |
|
|
|
help() { |
|
echo "Create new instance with something like:" |
|
echo "\"lxc init $new_image_name kde\"" |
|
echo "\"lxc config device add kde xspicesocket proxy bind=host listen=unix:/tmp/kde.unix connect=unix:/run/xspice/spice.unix uid=1000 gid=1000\"" |
|
echo "\"lxc start kde\"" |
|
echo "Connect virt-viewer with:" |
|
echo "\"remote-viewer spice+unix:///tmp/kde.unix\"" |
|
} |
|
|
|
if lxc image info local:$new_image_name &> /dev/null; then |
|
help |
|
exit |
|
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 |
|
|
|
# first we create an instance for building the required patched binaries |
|
lxc launch $BASE_IMAGE_NAME $instance_name |
|
|
|
|
|
# patch logind to allow creating a session on seat0 without a real vt |
|
cat > f << "EOF" |
|
diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c |
|
index d85f897..34b743a 100644 |
|
--- a/src/login/logind-dbus.c |
|
+++ b/src/login/logind-dbus.c |
|
@@ -768,6 +768,7 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus |
|
"Console TTY specified but VT number is not 0"); |
|
} |
|
|
|
+ vtnr = 0; |
|
if (seat) { |
|
if (seat_has_vts(seat)) { |
|
if (vtnr <= 0 || vtnr > 63) |
|
|
|
EOF |
|
lxc file push f $instance_name/systemd.diff |
|
|
|
# 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 << EOF |
|
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 systemd spice-vdagent xserver-xspice |
|
apt install -y fakeroot |
|
|
|
adduser --disabled-password --gecos "$GECOS" $USERNAME |
|
|
|
mkdir -p /output |
|
chown 1000:1000 /output |
|
EOF |
|
|
|
# patch and build packages |
|
lxc exec $instance_name -- su $USERNAME << "EOF" |
|
cd |
|
apt source systemd spice-vdagent xserver-xspice |
|
cd systemd-* |
|
patch -p1 < /systemd.diff |
|
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -b -uc -us |
|
cp -v debian/systemd/lib/systemd/systemd-logind /output |
|
cd |
|
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/systemd-logind . |
|
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 |
|
|
|
# create a new one where we will build the final image |
|
lxc launch $BASE_IMAGE_NAME $instance_name |
|
|
|
lxc exec $instance_name bash << EOF |
|
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/bin/Xorg.real --rename /usr/bin/Xorg |
|
dpkg-divert --divert /usr/sbin/spice-vdagentd.real --rename /usr/sbin/spice-vdagentd |
|
dpkg-divert --divert /usr/lib/systemd/systemd-logind.real --rename /usr/lib/systemd/systemd-logind |
|
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 |
|
EOF |
|
|
|
lxc file push systemd-logind $instance_name/usr/lib/systemd/systemd-logind |
|
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:*] |
|
greeter-hide-users=false |
|
EOF |
|
|
|
mkdir -pv /etc/X11 |
|
cat > /etc/X11/xspice.xorg.conf << "EOF" |
|
Section "Device" |
|
Identifier "XSPICE" |
|
Driver "spiceqxl" |
|
|
|
Option "SpiceDisableTicketing" "True" |
|
Option "SpiceAddr" "/run/xspice/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 > /usr/bin/Xorg << "EOF" |
|
#!/bin/sh |
|
|
|
filtered_xorg_args="$(echo $* | sed -e 's/vt[0-9]//' -e 's/.novtswitch//' -e 's/.core//')" |
|
|
|
exec /usr/lib/xorg/Xorg -config /etc/X11/xspice.xorg.conf -noreset $filtered_xorg_args |
|
EOF |
|
chmod +x /usr/bin/Xorg |
|
|
|
export DEBIAN_FRONTEND=noninteractive |
|
|
|
apt install -y xserver-xspice spice-vdagent pulseaudio |
|
systemctl enable spice-vdagent.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 |
|
|
|
# setup KDE, need to hold sddm since it only works if patched |
|
lxc exec $instance_name bash << "EOF" |
|
apt-mark hold sddm |
|
apt install -y kde-full lightdm firefox-esr |
|
EOF |
|
|
|
lxc stop $instance_name |
|
lxc publish $instance_name --alias=$new_image_name |
|
|
|
help |