{ pkgs, lib, config, hypervisorConfig, ... }: { imports = [ ./docker_swarm.nix ]; options.lab.vm = { baseMACAddress = lib.mkOption { default = "BA:DB:EE:F0:00:00"; type = lib.types.str; description = '' Base MAC address for VMs in the DMZ. ''; }; id = lib.mkOption { type = lib.types.int; description = '' Unique identifier of this VM from wich the MAC address is derived. ''; }; staticNetworking = lib.mkOption { default = false; type = lib.types.bool; description = '' Whether this VM has static networking configuration applied. Routing is prepopulated, but IP addresses have to be set. ''; }; staticIPv4 = lib.mkOption { type = lib.types.str; description = '' Static IPv4 address for the VM. ''; }; staticIPv6 = lib.mkOption { type = lib.types.str; description = '' Static IPv6 address for the VM. ''; }; shares = lib.mkOption { default = [ ]; description = '' Directories mounted on the VM using VirtioFS. ''; type = lib.types.listOf (lib.types.submodule ({ config, ... }: { options = { name = lib.mkOption { type = lib.types.str; description = '' The name of the directory share. ''; }; mountPoint = lib.mkOption { type = lib.types.str; description = '' The mount point of the directory share inside the virtual machine. ''; }; }; })); }; }; config = { system.stateVersion = hypervisorConfig.system.stateVersion; lab.vm.shares = [{ name = "host_keys"; mountPoint = "/etc/ssh/host_keys"; }]; services.openssh = { hostKeys = [{ path = "/etc/ssh/host_keys/ssh_host_ed25519_key"; type = "ed25519"; }]; extraConfig = '' HostKey /etc/ssh/host_keys/ssh_host_ed25519_key ''; }; microvm = { # TODO: make this dependent on the host CPU vcpu = 4; shares = [{ source = "/nix/store"; mountPoint = "/nix/.ro-store"; tag = "ro-store"; proto = "virtiofs"; }] ++ map (share: { source = "/var/lib/microvms/${config.networking.hostName}/shares/${share.name}"; mountPoint = share.mountPoint; tag = share.name; proto = "virtiofs"; }) config.lab.vm.shares; interfaces = [{ type = "tap"; id = "vm-${config.networking.hostName}"; mac = pkgs.lib.net.mac.add config.lab.vm.id config.lab.vm.baseMACAddress; }]; }; networking.useDHCP = false; systemd.network = let cfg = config.lab.networking; in { enable = true; networks = { "30-main-nic" = { matchConfig.Name = "en*"; networkConfig = { IPv6AcceptRA = ! config.lab.vm.staticNetworking; DHCP = lib.mkIf (! config.lab.vm.staticNetworking) "yes"; Address = lib.mkIf config.lab.vm.staticNetworking [ "${ config.lab.vm.staticIPv4}/${cfg.dmz.ipv4.prefixLength}" "${config.lab.vm.staticIPv6}/${cfg.dmz.ipv6.prefixLength}" ]; DNS = lib.mkIf config.lab.vm.staticNetworking [ cfg.dmz.ipv4.router cfg.dmz.ipv6.router ]; }; routes = lib.mkIf config.lab.vm.staticNetworking [ { routeConfig = { Gateway = cfg.dmz.ipv4.router; Destination = "0.0.0.0/0"; }; } { routeConfig = { Gateway = cfg.dmz.ipv6.router; Destination = "::/0"; }; } ]; }; }; }; }; }