{ pkgs ? import {}, system ? builtins.currentSystem, nixvirt, }: let inherit (nixvirt) lib; vm = import ./lib/vm.nix { inherit pkgs nixvirt; }; osdb = import ./db.nix { inherit pkgs system; }; volumeFn = { name, size }: nixvirt.lib.volume.writeXML { name = name + ".qcow2"; capacity = { count = size; unit = "GB"; }; target = { format.type = "qcow2"; }; }; in { inherit osdb; mkVM = { name, uuid, arch, isos, }: let base = { inherit name uuid arch; volume.index = 0; volume.bus = "sata"; volume.file = "/var/lib/libvirt/images/${name}.qcow2"; }; idxToDev = i: builtins.substring i 1 "abcdefg"; volume = volumeFn { size = 16; inherit name; }; beforeInstall = isos.beforeInstall; # Required attribute. afterInstall = if builtins.hasAttr "afterInstall" isos then isos.afterInstall else []; beforeBoot = if builtins.hasAttr "beforeBoot" isos then isos.beforeBoot else []; afterBoot = if builtins.hasAttr "afterBoot" isos then isos.afterBoot else []; beforeInstallDrv = lib.domain.writeXML (vm.genericVM (base // { cdroms = map (x: { inherit (x) index file; bus = "sata"; dev = "sd" + idxToDev x.index; }) (beforeInstall); })); afterInstallDrv = lib.domain.writeXML (vm.genericVM (base // { cdroms = map (x: { inherit (x) index file; bus = "sata"; dev = "sd" + idxToDev x.index; }) (afterInstall); })); beforeBootDrv = lib.domain.writeXML (vm.genericVM (base // { cdroms = map (x: { inherit (x) index file; bus = "sata"; dev = "sd" + idxToDev x.index; }) (beforeBoot); })); afterBootDrv = lib.domain.writeXML (vm.genericVM (base // { cdroms = map (x: { inherit (x) index file; bus = "sata"; dev = "sd" + idxToDev x.index; }) (afterBoot); })); in derivation { inherit name system; builder = "${pkgs.fish}/bin/fish"; args = [ ./lib/mkvm.fish ]; start-vm = pkgs.writeScript "start-vm" '' #!/usr/bin/env fish function quickExit virsh destroy ${name} exit end function interrupt_handler --on-signal INT echo Got INT signal, cleaning up and exiting... quickExit end echo "moving to beforeInstall stage" # rm /var/lib/libvirt/images/${name}.qcow2 # virsh vol-delete --pool default '${name}.qcow2' virsh vol-create default ${volume} virsh define ${beforeInstallDrv} virsh start '${name}' fish -c 'virsh console ${name} 2>/dev/null | while read -l out; if test $out = "$(string unescape ready\r\n)"; sleep 60; exit; end; end' # virsh console '${name}' 2>/dev/null | while read -l out # # echo out: $out (string unescape \r) # if test $out = "$(string unescape ready\r\n)" # echo "waiting 60 seconds" # sleep 60 # virsh shutdown '${name}' # end # end echo "moving to afterInstall stage" virsh define ${afterInstallDrv} virsh snapshot-create-as '${name}' '${builtins.baseNameOf afterInstallDrv}' virsh console '${name}' 2>/dev/null | while read -l out if test $out = "$(string unescape ready\r\n)" echo "waiting 60 seconds" sleep 60 virsh shutdown '${name}' end end echo "moving to beforeBoot stage" virsh define ${beforeBootDrv} virsh snapshot-create-as '${name}' '${builtins.baseNameOf beforeBootDrv}' virsh console '${name}' 2>/dev/null | while read -l out if test $out = "$(string unescape ready\r\n)" echo "waiting 60 seconds" sleep 60 virsh shutdown '${name}' end end echo "moving to afterBoot stage" virsh define ${afterBootDrv} virsh snapshot-create-as '${name}' '${builtins.baseNameOf afterBootDrv}' ''; }; }