From 906026e924e3aac0f0ed32ec8ab2f7468e8e1c0a Mon Sep 17 00:00:00 2001 From: Emile Date: Mon, 10 Feb 2025 23:58:05 +0100 Subject: corrino: libvirtnix foo, less XML, more nix! So I've finally started this. Let's see how far I can push this! --- nix/modules/libvirtnix/default.nix | 102 +++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 nix/modules/libvirtnix/default.nix (limited to 'nix/modules/libvirtnix/default.nix') diff --git a/nix/modules/libvirtnix/default.nix b/nix/modules/libvirtnix/default.nix new file mode 100644 index 0000000..4689979 --- /dev/null +++ b/nix/modules/libvirtnix/default.nix @@ -0,0 +1,102 @@ +{ + 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; + }; +} -- cgit 1.4.1