forked from pub-solar/os
98 lines
3.6 KiB
Nix
98 lines
3.6 KiB
Nix
{ config, pkgs, lib, vm, ... }:
|
|
let
|
|
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;
|
|
in
|
|
{
|
|
serviceConfig = {
|
|
Type = "oneshot";
|
|
RemainAfterExit = "yes";
|
|
Restart = "no";
|
|
};
|
|
|
|
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
|
|
|
|
echo "Creating network XML"
|
|
NET_TMP_FILE="/tmp/network.xml"
|
|
|
|
NETUUID="$(${pkgs.libvirt}/bin/virsh net-uuid 'default' || true)"
|
|
(sed "s/UUID/$NETUUID/" '${networkXML}') > "$NET_TMP_FILE"
|
|
|
|
echo "Defining and starting network"
|
|
${pkgs.libvirt}/bin/virsh net-define "$NET_TMP_FILE"
|
|
${pkgs.libvirt}/bin/virsh net-start 'default' || true
|
|
|
|
VARS_FILE=${varsFile}
|
|
if [ ! -f "$VARS_FILE" ]; then
|
|
echo "Copying vars filej"
|
|
cp /run/libvirt/nix-ovmf/OVMF_VARS.fd "$VARS_FILE"
|
|
fi
|
|
|
|
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"
|
|
|
|
# Set VM UUID
|
|
UUID="$(${pkgs.libvirt}/bin/virsh domuuid '${vm.name}' || true)"
|
|
sed -i "s/UUID/''${UUID}/" "$TMP_FILE"
|
|
|
|
${if vm.handOverUSBDevices then ''
|
|
# Hand over mouse
|
|
USB_BUS=5
|
|
USB_DEV=$(${pkgs.usbutils}/bin/lsusb | grep 046d:c52b | grep 'Bus 005' | cut -b 18)
|
|
LINE_NUMBER=$(cat $TMP_FILE | grep -n -A 1 0xc52b | tail -n 1 | cut -b 1,2,3)
|
|
sed -i "''${LINE_NUMBER}s/.*/<address bus=\"''${USB_BUS}\" device=\"''${USB_DEV}\" \/>/" "$TMP_FILE"
|
|
|
|
# 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"
|
|
'' else ""}
|
|
|
|
# TODO: Set correct pci address for the GPU too
|
|
|
|
# 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
|
|
|
|
# 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}'
|
|
'';
|
|
|
|
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
|
|
|
|
${pkgs.libvirt}/bin/virsh net-destroy 'default' || true
|
|
'';
|
|
}
|