{ config, lib, pkgs, ... }: let cfg = config.services.emile.libvirtnix; in { options.services.emile.libvirtnix = with lib; { enable = mkEnableOption "enable libvirtnix"; instances = mkOption { type = types.attrsOf ( types.submodule ( { name, ... }: { options = { enable = mkEnableOption "enable this instance"; domain = mkOption { type = types.submodule (import ./domain.nix); }; }; } ) ); default = { }; description = '' A full libvirt config, statically defined using nix. ''; example = '' { domain = { name = "vm"; }; } ''; }; }; config = lib.mkIf cfg.enable { systemd.services = lib.mapAttrs' ( name: guest: lib.nameValuePair "libvirtd-guest-${name}" { after = [ "libvirtd.service" ]; requires = [ "libvirtd.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = "yes"; }; script = let xml = pkgs.writeText "libvirt-guest-${name}.xml" '''' + (lib.optionalString (guest.domain.name != "") "${guest.domain.name}") + (lib.optionalString (guest.domain.name != "") "${guest.domain.name}") + (lib.optionalString (guest.domain.uuid != "") "${guest.domain.uuid}") + (lib.optionalString (guest.domain.genid != "") "${guest.domain.genid}") + (lib.optionalString (guest.domain.title != "") "${guest.domain.title}") + (lib.optionalString ( guest.domain.description != "" ) "${guest.domain.description}") + (lib.optionalString (guest.domain.metadata != "") "${guest.domain.metadata}") + '' hvm ${toString guest.domain.memory} ''; in '' uuid="$(${pkgs.libvirt}/bin/virsh domuuid '${name}' || true)" ${pkgs.libvirt}/bin/virsh define <(sed "s/UUID/$uuid/" '${xml}') ${pkgs.libvirt}/bin/virsh start '${name}' ''; preStop = '' ${pkgs.libvirt}/bin/virsh shutdown '${name}' let "timeout = $(date +%s) + 10" while [ "$(${pkgs.libvirt}/bin/virsh list --name | grep --count '^${name}$')" -gt 0 ]; do if [ "$(date +%s)" -ge "$timeout" ]; then # Meh, we warned it... ${pkgs.libvirt}/bin/virsh destroy '${name}' else # The machine is still running, let's give it some time to shut down sleep 0.5 fi done ''; } ) config.services.emile.libvirtnix.instances; }; }