os/hosts/chocolatebar/virtualisation/create-service.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

113 lines
3.6 KiB
Nix
Raw Permalink Normal View History

2023-01-28 21:27:52 +00:00
{
config,
pkgs,
lib,
vm,
...
}: let
2021-05-30 19:33:09 +00:00
psCfg = config.pub-solar;
xdg = config.home-manager.users."${psCfg.user.name}".xdg;
varsFile = "${xdg.dataHome}/libvirt/OVMF_VARS_${vm.name}.fd";
generateXML = import ./guest-xml.nix;
2023-01-28 21:27:52 +00:00
in {
2021-05-30 19:33:09 +00:00
serviceConfig = {
Type = "oneshot";
RemainAfterExit = "yes";
Restart = "no";
};
2023-01-28 21:27:52 +00:00
script = let
networkXML = pkgs.writeText "network.xml" (import ./network-xml.nix {
inherit config;
inherit pkgs;
inherit lib;
});
machineXML = pkgs.writeText "${vm.name}.xml" (vm.generateXML {
inherit config;
inherit pkgs;
inherit lib;
inherit vm;
varsFile = varsFile;
});
in ''
echo "Checking if ${vm.name} is already running"
STATUS=$(${pkgs.libvirt}/bin/virsh list --all | grep "${vm.name}" | ${pkgs.gawk}/bin/awk '{ print $3 " " $4 }' )
if [[ $STATUS != "shut off" && $STATUS != "" ]]; then
echo "Domain ${vm.name} is already running or in an inconsistent state:"
${pkgs.libvirt}/bin/virsh list --all
exit 0
fi
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
echo "Creating network XML"
NET_TMP_FILE="/tmp/network.xml"
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
NETUUID="$(${pkgs.libvirt}/bin/virsh net-uuid 'default' || true)"
(sed "s/UUID/$NETUUID/" '${networkXML}') > "$NET_TMP_FILE"
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
echo "Defining and starting network"
${pkgs.libvirt}/bin/virsh net-define "$NET_TMP_FILE"
${pkgs.libvirt}/bin/virsh net-start 'default' || true
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
VARS_FILE=${varsFile}
if [ ! -f "$VARS_FILE" ]; then
echo "Copying vars filej"
cp /run/libvirt/nix-ovmf/OVMF_VARS.fd "$VARS_FILE"
fi
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
echo "Replacing USB device IDs in the XML"
# Load the template contents into a tmp file
TMP_FILE="/tmp/${vm.name}.xml"
cat "${machineXML}" > "$TMP_FILE"
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
# Set VM UUID
UUID="$(${pkgs.libvirt}/bin/virsh domuuid '${vm.name}' || true)"
sed -i "s/UUID/''${UUID}/" "$TMP_FILE"
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
${
if vm.handOverUSBDevices
then ''
2022-02-14 09:50:26 +00:00
# Hand over mouse
USB_BUS=3
USB_DEV=$(${pkgs.usbutils}/bin/lsusb | grep 046d:c52b | grep "Bus 00''${USB_BUS}" | cut -b 18)
LINE_NUMBER=$(cat $TMP_FILE | grep -n -A 1 0xc52b | tail -n 1 | cut -b 1,2,3)
2022-10-24 19:44:40 +00:00
sed -i "''${LINE_NUMBER}s/.*/<address bus=\"''${USB_BUS}\" device=\"''${USB_DEV}\" \/>/" "$TMP_FILE"
2021-05-30 19:33:09 +00:00
2022-02-14 09:50:26 +00:00
# Hand over keyboard
USB_BUS=$(${pkgs.usbutils}/bin/lsusb | grep 046d:c328 | cut -b 7)
USB_DEV=$(${pkgs.usbutils}/bin/lsusb | grep 046d:c328 | cut -b 18)
LINE_NUMBER=$(cat $TMP_FILE | grep -n -A 1 0xc328 | tail -n 1 | cut -b 1,2,3)
sed -i "''${LINE_NUMBER}s/.*/<address bus=\"''${USB_BUS}\" device=\"''${USB_DEV}\" \/>/" "$TMP_FILE"
2023-01-28 21:27:52 +00:00
''
else ""
}
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
# TODO: Set correct pci address for the GPU too
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
# Setup looking glass shm file
echo "Setting up looking glass shm file"
${pkgs.coreutils-full}/bin/truncate -s 0 /dev/shm/looking-glass
${pkgs.coreutils-full}/bin/dd if=/dev/zero of=/dev/shm/looking-glass bs=1M count=32
2023-01-28 21:27:52 +00:00
# Load and start the xml definition
echo "Loading and starting the VM XML definition"
${pkgs.libvirt}/bin/virsh define "$TMP_FILE"
${pkgs.libvirt}/bin/virsh start '${vm.name}'
'';
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
preStop = ''
${pkgs.libvirt}/bin/virsh shutdown '${vm.name}'
let "timeout = $(date +%s) + 10"
while [ "$(${pkgs.libvirt}/bin/virsh list --name | grep --count '^${vm.name}$')" -gt 0 ]; do
if [ "$(date +%s)" -ge "$timeout" ]; then
# Meh, we warned it...
${pkgs.libvirt}/bin/virsh destroy '${vm.name}'
else
# The machine is still running, let's give it some time to shut down
sleep 0.5
fi
done
2021-05-30 19:33:09 +00:00
2023-01-28 21:27:52 +00:00
${pkgs.libvirt}/bin/virsh net-destroy 'default' || true
'';
2021-05-30 19:33:09 +00:00
}