diff --git a/flake.nix b/flake.nix index f10eb34..782ff27 100644 --- a/flake.nix +++ b/flake.nix @@ -84,8 +84,8 @@ nodes = mkDeployNodes (name: machine: { hostname = self.nixosConfigurations.${name}.config.networking.fqdn; profiles.system = { - remoteBuild = true; - path = deploy-rs.lib."aarch64-linux".activate.nixos + remoteBuild = machine.arch != "x86_64-linux"; + path = deploy-rs.lib."${machine.arch}".activate.nixos self.nixosConfigurations.${name}; }; }); diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index 7cdf2a1..0642755 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -1,7 +1,12 @@ +# TODO: Create a nixos module system for this. (mkMerge) +# That way, we don't have to specify isRaspberryPi on every machine... etc. { warwick = { type = "physical"; arch = "aarch64-linux"; + isRaspberryPi = true; + isHypervisor = false; + isVirtualMachine = false; nixosModule.lab = { storage = { @@ -13,6 +18,9 @@ atlas = { type = "physical"; arch = "x86_64-linux"; + isRaspberryPi = false; + isHypervisor = true; + isVirtualMachine = false; nixosModule.lab = { storage = { @@ -31,19 +39,20 @@ jefke = { type = "physical"; arch = "x86_64-linux"; + isRaspberryPi = false; + isHypervisor = true; + isVirtualMachine = false; - nixosModule = { - lab = { - storage = { - osDisk = "/dev/sda"; - dataPartition = "/dev/nvme0n1p1"; - }; + nixosModule.lab = { + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; + }; - ssh = { - useCertificates = true; - hostCert = builtins.readFile ./certificates/jefke/host_ed25519.crt; - userCert = builtins.readFile ./certificates/jefke/user_ed25519.crt; - }; + ssh = { + useCertificates = true; + hostCert = builtins.readFile ./certificates/jefke/host_ed25519.crt; + userCert = builtins.readFile ./certificates/jefke/user_ed25519.crt; }; }; }; @@ -51,6 +60,9 @@ lewis = { type = "physical"; arch = "x86_64-linux"; + isRaspberryPi = false; + isHypervisor = true; + isVirtualMachine = false; nixosModule.lab = { backups.enable = true; @@ -73,18 +85,23 @@ hermes = { type = "virtual"; hypervisorName = "lewis"; + isRaspberryPi = false; + isVirtualMachine = true; + isHypervisor = false; nixosModule = { config, ... }: { lab = { - networking.dmz.services.enable = true; + networking = { + dmz.services.enable = true; + staticNetworking = true; + staticIPv4 = config.lab.networking.dmz.ipv4.services; + staticIPv6 = config.lab.networking.dmz.ipv6.services; + }; vm = { # TODO: would be cool to create a check that a mac address is only ever assigned to one VM. # TODO: idea: what if we generated these IDs by hashing the host name and reducing that to the amount of hosts possible? id = 7; - staticNetworking = true; - staticIPv4 = config.lab.networking.dmz.ipv4.services; - staticIPv6 = config.lab.networking.dmz.ipv6.services; shares = [{ name = "dnsmasq"; @@ -98,6 +115,9 @@ maestro = { type = "virtual"; hypervisorName = "atlas"; + isRaspberryPi = false; + isVirtualMachine = false; + isHypervisor = false; nixosModule = { config, ... }: { microvm.balloonMem = 7680; @@ -115,6 +135,9 @@ bancomart = { type = "virtual"; hypervisorName = "jefke"; + isRaspberryPi = false; + isVirtualMachine = false; + isHypervisor = false; nixosModule = { microvm.balloonMem = 7680; @@ -129,6 +152,9 @@ vpay = { type = "virtual"; hypervisorName = "lewis"; + isRaspberryPi = false; + isVirtualMachine = false; + isHypervisor = false; nixosModule = { microvm.balloonMem = 5120; diff --git a/nixos/modules/networking/default.nix b/nixos/modules/networking/default.nix index 577e3e1..40f6404 100644 --- a/nixos/modules/networking/default.nix +++ b/nixos/modules/networking/default.nix @@ -22,11 +22,26 @@ in { }; }; - mainNicNamePattern = lib.mkOption { - default = "en*"; + staticNetworking = lib.mkOption { + default = false; + type = lib.types.bool; + description = '' + Whether this machine has static networking configuration applied. + Routing is prepopulated, but IP addresses have to be set. + ''; + }; + + staticIPv4 = lib.mkOption { type = lib.types.str; description = '' - Pattern to match the name of this machine's main NIC. + Static IPv4 address for the machine. + ''; + }; + + staticIPv6 = lib.mkOption { + type = lib.types.str; + description = '' + Static IPv6 address for the machine. ''; }; }; @@ -35,7 +50,7 @@ in { networking = { domain = if machine.type == "physical" then "hyp" else "dmz"; nftables.enable = true; - useDHCP = true; + useDHCP = false; firewall = { enable = true; @@ -43,10 +58,10 @@ in { }; }; - systemd.network = lib.mkIf (false && machine.type == "physical") { + systemd.network = { enable = true; - netdevs = { + netdevs = lib.mkIf machine.isHypervisor { "20-vlandmz" = { vlanConfig.Id = 30; @@ -64,43 +79,89 @@ in { }; }; - networks = { - "30-main-nic" = { - matchConfig.Name = cfg.mainNicNamePattern; - vlan = [ "vlandmz" ]; + networks = lib.attrsets.mergeAttrsList [ + (lib.optionalAttrs machine.isHypervisor { + "30-main-nic" = { + matchConfig.Name = "en*"; + vlan = [ "vlandmz" ]; - networkConfig = { - DHCP = "yes"; + networkConfig = { + DHCP = "yes"; + }; }; - }; - "40-vlandmz" = { - matchConfig.Name = "vlandmz"; - linkConfig.RequiredForOnline = "enslaved"; + "40-vlandmz" = { + matchConfig.Name = "vlandmz"; + linkConfig.RequiredForOnline = "enslaved"; - networkConfig = { - IPv6AcceptRA = false; - LinkLocalAddressing = "no"; - Bridge = cfg.dmz.bridgeName; + networkConfig = { + IPv6AcceptRA = false; + LinkLocalAddressing = "no"; + Bridge = cfg.dmz.bridgeName; + }; }; - }; - "40-bridgedmz" = { - matchConfig.Name = cfg.dmz.bridgeName; - linkConfig.RequiredForOnline = "carrier"; + "40-bridgedmz" = { + matchConfig.Name = cfg.dmz.bridgeName; + linkConfig.RequiredForOnline = "carrier"; - networkConfig = { - IPv6AcceptRA = cfg.dmz.allowConnectivity; - LinkLocalAddressing = if cfg.dmz.allowConnectivity then "ipv6" else "no"; - DHCP = "yes"; + networkConfig = { + IPv6AcceptRA = cfg.dmz.allowConnectivity; + LinkLocalAddressing = if cfg.dmz.allowConnectivity then "ipv6" else "no"; + DHCP = "yes"; + }; }; - }; - "40-vms" = { - matchConfig.Name = "vm-*"; - networkConfig.Bridge = cfg.dmz.bridgeName; - }; - }; + "40-vms" = { + matchConfig.Name = "vm-*"; + networkConfig.Bridge = cfg.dmz.bridgeName; + }; + }) + (lib.optionalAttrs machine.isVirtualMachine { + "30-main-nic" = { + matchConfig.Name = "en*"; + + networkConfig = { + IPv6AcceptRA = ! cfg.staticNetworking; + DHCP = lib.mkIf (! cfg.staticNetworking) "yes"; + + Address = lib.mkIf cfg.staticNetworking [ + "${cfg.staticIPv4}/${cfg.dmz.ipv4.prefixLength}" + "${cfg.staticIPv6}/${cfg.dmz.ipv6.prefixLength}" + ]; + + DNS = lib.mkIf cfg.staticNetworking [ + cfg.dmz.ipv4.router + cfg.dmz.ipv6.router + ]; + }; + + routes = lib.mkIf cfg.staticNetworking [ + { + routeConfig = { + Gateway = cfg.dmz.ipv4.router; + Destination = "0.0.0.0/0"; + }; + } + { + routeConfig = { + Gateway = cfg.dmz.ipv6.router; + Destination = "::/0"; + }; + } + ]; + }; + }) + (lib.optionalAttrs machine.isRaspberryPi { + "30-main-nic" = { + matchConfig.Name = "end*"; + networkConfig = { + IPv6AcceptRA = true; + DHCP = "yes"; + }; + }; + }) + ]; }; }; } diff --git a/nixos/modules/storage.nix b/nixos/modules/storage.nix index 6611546..94e3365 100644 --- a/nixos/modules/storage.nix +++ b/nixos/modules/storage.nix @@ -26,40 +26,51 @@ in { }; }; - config = lib.mkIf (false && machine.type == "physical") { - fileSystems.${cfg.dataMountPoint} = lib.mkIf (! isNull cfg.dataPartition) { - device = cfg.dataPartition; - }; + config = { + fileSystems = lib.attrsets.mergeAttrsList [ + (lib.optionalAttrs machine.isHypervisor { + "${cfg.dataMountPoint}".device = cfg.dataPartition; + }) + (lib.optionalAttrs machine.isRaspberryPi { + "/" = { + device = "/dev/disk/by-label/NIXOS_SD"; + fsType = "ext4"; + options = [ "noatime" ]; + }; + }) + ]; # TODO: Rename this to 'osDisk'. Unfortunately, we would need to run nixos-anywhere again then. - disko.devices.disk.vdb = { - device = cfg.osDisk; - type = "disk"; + disko = lib.mkIf machine.isHypervisor { + devices.disk.vdb = { + device = cfg.osDisk; + type = "disk"; - content = { - type = "gpt"; + content = { + type = "gpt"; - partitions = { - swap.size = "100%"; + partitions = { + swap.size = "100%"; - ESP = { - type = "EF00"; - size = "500M"; + ESP = { + type = "EF00"; + size = "500M"; - content = { - type = "filesystem"; - format = "vfat"; - mountpoint = "/boot"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; }; - }; - root = { - end = "-4G"; + root = { + end = "-4G"; - content = { - type = "filesystem"; - format = "btrfs"; - mountpoint = "/"; + content = { + type = "filesystem"; + format = "btrfs"; + mountpoint = "/"; + }; }; }; }; diff --git a/nixos/physical.nix b/nixos/physical.nix index 13251f3..9b6e0af 100644 --- a/nixos/physical.nix +++ b/nixos/physical.nix @@ -1,55 +1,40 @@ -{ pkgs, config, lib, modulesPath, microvm, disko, agenix, machines, dns, machine, nixos-hardware, ... }: { +{ pkgs, config, lib, microvm, disko, agenix, machine, machines, dns, nixos-hardware, ... }: { imports = [ - (modulesPath + "/installer/scan/not-detected.nix") microvm.nixosModules.host - nixos-hardware.nixosModules.raspberry-pi-4 - ]; + ] + ++ lib.lists.optional (machine.isRaspberryPi) nixos-hardware.nixosModules.raspberry-pi-4; config = { + boot = lib.mkIf (machine.isHypervisor) { + kernelModules = [ "kvm-intel" ]; + extraModulePackages = [ ]; - fileSystems = { - "/" = { - device = "/dev/disk/by-label/NIXOS_SD"; - fsType = "ext4"; - options = [ "noatime" ]; + initrd = { + availableKernelModules = [ + "ahci" + "xhci_pci" + "nvme" + "usbhid" + "usb_storage" + "sd_mod" + "sdhci_pci" + ]; + kernelModules = [ ]; + }; + + loader = { + systemd-boot.enable = true; + efi.canTouchEfiVariables = true; }; }; - # boot.loader.grub.device = "/dev/sda"; - # boot.loader.grub.enable = true; - # boot.loader.grub.efiSupport = true; - # boot.loader.grub.efiInstallAsRemovable = true; - # boot.loader.grub.device = "nodev"; - # boot = { - # # kernelModules = [ "kvm-intel" ]; - # kernelModules = [ ]; - # extraModulePackages = [ ]; - - # initrd = { - # availableKernelModules = [ - # "ahci" - # "xhci_pci" - # "nvme" - # "usbhid" - # "usb_storage" - # "sd_mod" - # "sdhci_pci" - # ]; - # kernelModules = [ ]; - # }; - - # loader = { - # # systemd-boot.enable = true; - # efi.canTouchEfiVariables = true; - # }; - # }; - nixpkgs = { config.allowUnfree = true; + # TODO: do we need this? # hostPlatform = machine.arch; }; - # hardware.cpu.intel.updateMicrocode = config.hardware.enableRedistributableFirmware; + hardware.cpu.intel.updateMicrocode = lib.mkIf (machine.isHypervisor) config.hardware.enableRedistributableFirmware; age.identityPaths = [ "/etc/age_ed25519" ]; diff --git a/nixos/virtual/default.nix b/nixos/virtual/default.nix index ad37f90..089fe41 100644 --- a/nixos/virtual/default.nix +++ b/nixos/virtual/default.nix @@ -2,6 +2,7 @@ imports = [ ./docker_swarm.nix ]; options.lab.vm = { + # TODO: make global. baseMACAddress = lib.mkOption { default = "BA:DB:EE:F0:00:00"; type = lib.types.str; @@ -17,29 +18,6 @@ ''; }; - 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 = '' @@ -73,16 +51,20 @@ mountPoint = "/etc/ssh/host_keys"; }]; - services.openssh = { - # hostKeys = [{ - # path = "/etc/ssh/host_keys/ssh_host_ed25519_key"; - # type = "ed25519"; - # }]; + services.openssh = + let + hostKeyPath = "/etc/ssh/host_keys/ssh_host_ed25519_key"; + in + { + hostKeys = [{ + path = hostKeyPath; + type = "ed25519"; + }]; - # extraConfig = '' - # HostKey /etc/ssh/host_keys/ssh_host_ed25519_key - # ''; - }; + extraConfig = '' + HostKey ${hostKeyPath} + ''; + }; microvm = { # TODO: make this dependent on the host CPU @@ -108,51 +90,5 @@ 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"; - }; - } - ]; - }; - }; - }; }; }