From e7f35bf1bd820df85ecf99c0fa304f16427719ec Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Thu, 29 Feb 2024 00:28:38 +0100 Subject: [PATCH] create module system for machines --- flake.nix | 2 +- nixos/machines/default.nix | 329 +++++++++++++++------------ nixos/modules/networking/default.nix | 2 +- 3 files changed, 186 insertions(+), 147 deletions(-) diff --git a/flake.nix b/flake.nix index 1989ac2..0c78971 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ pkgs = nixpkgs.legacyPackages.${controllerArch}; lib = pkgs.lib; pkgs-unstable = nixpkgs-unstable.legacyPackages.${controllerArch}; - machines = import ./nixos/machines; + machines = (lib.modules.evalModules { modules = [ (import ./nixos/machines) ]; }).config.machines; physicalMachines = lib.filterAttrs (n: v: v.type == "physical") machines; mkNixosSystems = systemDef: builtins.mapAttrs diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index 0642755..259b8a6 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -1,167 +1,206 @@ -# TODO: Create a nixos module system for this. (mkMerge) -# That way, we don't have to specify isRaspberryPi on every machine... etc. +{ lib, ... }: +let + machineOpts = { ... }: { + options = { + # TODO: rename to kind? + type = lib.mkOption { + type = lib.types.enum [ "physical" "virtual" ]; + description = '' + Whether this machine is physical or virtual. + ''; + }; + + hypervisorName = lib.mkOption { + default = null; + type = with lib.types; nullOr str; + description = '' + The host name of the hypervisor hosting this virtual machine. + ''; + }; + + arch = lib.mkOption { + default = null; + type = with lib.types; nullOr str; + description = '' + CPU architecture of this machine. + ''; + }; + + isRaspberryPi = lib.mkOption { + default = false; + type = lib.types.bool; + }; + + isHypervisor = lib.mkOption { + default = false; + type = lib.types.bool; + }; + + nixosModule = lib.mkOption { + default = { ... }: { }; + type = lib.types.anything; + description = '' + Customized configuration for this machine in the form of a NixOS module. + ''; + }; + }; + }; +in { - warwick = { - type = "physical"; - arch = "aarch64-linux"; - isRaspberryPi = true; - isHypervisor = false; - isVirtualMachine = false; - - nixosModule.lab = { - storage = { - osDisk = "/dev/sda"; - }; + options = { + machines = lib.mkOption { + type = with lib.types; attrsOf (submodule machineOpts); }; }; - atlas = { - type = "physical"; - arch = "x86_64-linux"; - isRaspberryPi = false; - isHypervisor = true; - isVirtualMachine = false; + config = { + machines = { + warwick = { + type = "physical"; + arch = "aarch64-linux"; + isRaspberryPi = true; - nixosModule.lab = { - storage = { - osDisk = "/dev/sda"; - dataPartition = "/dev/nvme0n1p1"; - }; - - ssh = { - useCertificates = true; - hostCert = builtins.readFile ./certificates/atlas/host_ed25519.crt; - userCert = builtins.readFile ./certificates/atlas/user_ed25519.crt; - }; - }; - }; - - jefke = { - type = "physical"; - arch = "x86_64-linux"; - isRaspberryPi = false; - isHypervisor = true; - isVirtualMachine = false; - - 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; - }; - }; - }; - - lewis = { - type = "physical"; - arch = "x86_64-linux"; - isRaspberryPi = false; - isHypervisor = true; - isVirtualMachine = false; - - nixosModule.lab = { - backups.enable = true; - data-sharing.enable = true; - networking.dmz.allowConnectivity = true; - - storage = { - osDisk = "/dev/sda"; - dataPartition = "/dev/nvme0n1p1"; - }; - - ssh = { - useCertificates = true; - hostCert = builtins.readFile ./certificates/lewis/host_ed25519.crt; - userCert = builtins.readFile ./certificates/lewis/user_ed25519.crt; - }; - }; - }; - - hermes = { - type = "virtual"; - hypervisorName = "lewis"; - isRaspberryPi = false; - isVirtualMachine = true; - isHypervisor = false; - - nixosModule = { config, ... }: { - lab = { - 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; - - shares = [{ - name = "dnsmasq"; - mountPoint = "/var/lib/dnsmasq"; - }]; + nixosModule.lab = { + storage = { + osDisk = "/dev/sda"; + }; }; }; - }; - }; - maestro = { - type = "virtual"; - hypervisorName = "atlas"; - isRaspberryPi = false; - isVirtualMachine = false; - isHypervisor = false; + atlas = { + type = "physical"; + arch = "x86_64-linux"; + isHypervisor = true; - nixosModule = { config, ... }: { - microvm.balloonMem = 7680; + nixosModule.lab = { + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; + }; - lab = { - dockerSwarm.enable = true; - - vm = { - id = 1; + ssh = { + useCertificates = true; + hostCert = builtins.readFile ./certificates/atlas/host_ed25519.crt; + userCert = builtins.readFile ./certificates/atlas/user_ed25519.crt; + }; }; }; - }; - }; - bancomart = { - type = "virtual"; - hypervisorName = "jefke"; - isRaspberryPi = false; - isVirtualMachine = false; - isHypervisor = false; + jefke = { + type = "physical"; + arch = "x86_64-linux"; + isHypervisor = true; - nixosModule = { - microvm.balloonMem = 7680; + nixosModule.lab = { + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; + }; - lab = { - dockerSwarm.enable = true; - vm.id = 2; + ssh = { + useCertificates = true; + hostCert = builtins.readFile ./certificates/jefke/host_ed25519.crt; + userCert = builtins.readFile ./certificates/jefke/user_ed25519.crt; + }; + }; }; - }; - }; - vpay = { - type = "virtual"; - hypervisorName = "lewis"; - isRaspberryPi = false; - isVirtualMachine = false; - isHypervisor = false; + lewis = { + type = "physical"; + arch = "x86_64-linux"; + isHypervisor = true; - nixosModule = { - microvm.balloonMem = 5120; + nixosModule.lab = { + backups.enable = true; + data-sharing.enable = true; + networking.dmz.allowConnectivity = true; - lab = { - dockerSwarm.enable = true; - vm.id = 3; + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; + }; + + ssh = { + useCertificates = true; + hostCert = builtins.readFile ./certificates/lewis/host_ed25519.crt; + userCert = builtins.readFile ./certificates/lewis/user_ed25519.crt; + }; + }; + }; + + hermes = { + type = "virtual"; + hypervisorName = "lewis"; + + nixosModule = { config, ... }: { + lab = { + networking = { + dmz.services.enable = true; + staticNetworking = true; + # TODO: This seems to cause infinite recursion? Really weird. + # staticIPv4 = config.lab.networking.dmz.ipv4.services; + # staticIPv6 = config.lab.networking.dmz.ipv6.services; + staticIPv4 = "192.168.30.7"; + staticIPv6 = "2a0d:6e00:1a77:30::7"; + }; + + 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; + + shares = [{ + name = "dnsmasq"; + mountPoint = "/var/lib/dnsmasq"; + }]; + }; + }; + }; + }; + + maestro = { + type = "virtual"; + hypervisorName = "atlas"; + + nixosModule = { config, ... }: { + microvm.balloonMem = 7680; + + lab = { + dockerSwarm.enable = true; + + vm = { + id = 1; + }; + }; + }; + }; + + bancomart = { + type = "virtual"; + hypervisorName = "jefke"; + + nixosModule = { + microvm.balloonMem = 7680; + + lab = { + dockerSwarm.enable = true; + vm.id = 2; + }; + }; + }; + + vpay = { + type = "virtual"; + hypervisorName = "lewis"; + + nixosModule = { + microvm.balloonMem = 5120; + + lab = { + dockerSwarm.enable = true; + vm.id = 3; + }; + }; }; }; }; diff --git a/nixos/modules/networking/default.nix b/nixos/modules/networking/default.nix index 40f6404..f428c28 100644 --- a/nixos/modules/networking/default.nix +++ b/nixos/modules/networking/default.nix @@ -117,7 +117,7 @@ in { networkConfig.Bridge = cfg.dmz.bridgeName; }; }) - (lib.optionalAttrs machine.isVirtualMachine { + (lib.optionalAttrs (machine.type == "virtual") { "30-main-nic" = { matchConfig.Name = "en*";