{ config, pkgs, lib, utils, ... }: with utils; with lib; let cfg = virtualisation.libvirtd; textfile = with types; coercedTo str (pkgs.writeText "spec.xml") path; domain = { options = { xml = mkOption { type = }; autostart = mkOption { type = types.bool; default = true; }; }; }; define = let python = pkgs.python27.withPackages (ps: with ps; [ libvirt ]); in dCfg: '' #!${python}/bin/python import libvirt import sys conn = libvirt.open(None); if conn == None: print('Failed to open connection to hypervisor', file=sys.stderr) sys.exit(1) xmlFile = open(${escapeShellArg dCfg.xml}, 'r') dom = conn.defineXML(xmlFile.read(), 0) xmlFile.close() if dom == None: print('Failed to define domain', file=sys.stderr) sys.exit(1) dom.setAutostart(${if dCfg.autostart then "1" else "0"}) conn.close() sys.exit(0) ''; in { options = { virtualisation.libvirtd = { domains = mkOption { type = with types; attrsOf (submodule guest); default = {}; }; }; }; config = mkIf (cfg.domains != {}) { systemd.services."libvirtd-guest@" = { after = [ "libvirtd.service" ]; bindsTo = [ "libvirtd.service" ]; before = [ "libvirt-guests.service" ]; serviceConfig = { Type = "oneshot"; RemainAfterExit = true; }; path = with pkgs; [ libvirtd ]; }; systemd.services = mapAttrs' (dName: dCfg: nameValuePair ("libvirtd-guest@" + escapeSystemdPath dName + ".service") { serviceConfig = { ExecStart = pkgs.writeScript (dName + ".py") (define dCfg); }; }) cfg.domains; systemd.services."libvirt-guests.service" = { wants = mapAttrsToList (dName: dCfg: "libvirtd-guest@" + escapeSystemdPath dName + ".service") cfg.domains; }; }; }