{ config, self, lib, inputs, options, pkgs, ... }: with lib; let cfg = config.services.malobeo.microvm; in { options = { services.malobeo.microvm = { enableHostBridge = mkOption { default = false; type = types.bool; description = lib.mdDoc "Setup bridge device for microvms."; }; enableHostBridgeUnstable = mkOption { default = false; type = types.bool; description = lib.mdDoc "Setup bridge device for microvms."; }; deployHosts = mkOption { default = []; type = types.listOf types.str; description = '' List hostnames of MicroVMs that should be automatically initializes and autostart ''; }; }; }; imports = [ inputs.microvm.nixosModules.host ]; config = { assertions = [ { assertion = !(cfg.enableHostBridgeUnstable && cfg.enableHostBridge); message = '' Only enableHostBridge or enableHostBridgeUnstable! Not Both! ''; } ]; systemd.network = mkIf (cfg.enableHostBridge || cfg.enableHostBridgeUnstable) { enable = true; # create a bride device that all the microvms will be connected to netdevs."10-microvm".netdevConfig = { Kind = "bridge"; Name = "microvm"; }; networks."10-microvm" = { matchConfig.Name = "microvm"; networkConfig = { DHCPServer = true; IPv6SendRA = true; }; addresses = if cfg.enableHostBridgeUnstable then [ { Address = "10.0.0.1/24"; } ] else [ { addressConfig.Address = "10.0.0.1/24"; } ]; }; # connect the vms to the bridge networks."11-microvm" = { matchConfig.Name = "vm-*"; networkConfig.Bridge = "microvm"; }; }; microvm.vms = let # Map the values to each hostname to then generate an Attrset using listToAttrs mapperFunc = name: { inherit name; value = { # Host build-time reference to where the MicroVM NixOS is defined # under nixosConfigurations flake = inputs.malobeo; # Specify from where to let `microvm -u` update later on updateFlake = "git+https://git.dynamicdiscord.de/kalipso/infrastructure"; }; }; in builtins.listToAttrs (map mapperFunc cfg.deployHosts); systemd.services = builtins.foldl' (services: name: services // { "microvm-update@${name}" = { description = "Update MicroVMs automatically"; after = [ "network-online.target" ]; wants = [ "network-online.target" ]; unitConfig.ConditionPathExists = "/var/lib/microvms/${name}"; serviceConfig = { LimitNOFILE = "1048576"; Type = "oneshot"; }; path = with pkgs; [ nix git ]; environment.HOME = config.users.users.root.home; script = '' /run/current-system/sw/bin/microvm -Ru ${name} ''; }; }) {} (cfg.deployHosts); systemd.timers = builtins.foldl' (timers: name: timers // { "microvm-update-${name}" = { wantedBy = [ "timers.target" ]; timerConfig = { Unit = "microvm-update@${name}.service"; # three times per hour OnCalendar = "*:0,20,40:00"; Persistent = true; }; }; }) {} (cfg.deployHosts); }; }