From d842d25eb9dba89147239da5db29abd0985be539 Mon Sep 17 00:00:00 2001 From: oddlama Date: Mon, 8 May 2023 17:13:40 +0200 Subject: [PATCH] feat: add microvm module to simplify setup --- flake.lock | 2 +- flake.nix | 11 +++- hosts/common/core/default.nix | 1 + hosts/common/core/system.nix | 3 +- hosts/ward/default.nix | 19 +------ hosts/ward/microvms/test/default.nix | 2 - modules/microvms.nix | 78 ++++++++++++++++++++++++++++ nix/generate-node.nix | 11 ++-- 8 files changed, 99 insertions(+), 28 deletions(-) create mode 100644 modules/microvms.nix diff --git a/flake.lock b/flake.lock index a7712df..274dfd1 100644 --- a/flake.lock +++ b/flake.lock @@ -258,7 +258,7 @@ }, "locked": { "lastModified": 1682972682, - "narHash": "sha256-IYInF92rLqqVk/dyugT2QVbVeEfYx1rbBJjbUlRD8oE=", + "narHash": "sha256-+XyTwr4jZuDlT5l/0LynDVtvdWj8WmAwDEP/2rZ+1hk=", "type": "git", "url": "file:///root/projects/microvm.nix" }, diff --git a/flake.nix b/flake.nix index 8e9f94e..9fd70a4 100644 --- a/flake.nix +++ b/flake.nix @@ -105,7 +105,16 @@ }; colmena = import ./nix/colmena.nix inputs; - inherit ((colmena.lib.makeHive self.colmena).introspect (x: x)) nodes; + colmenaNodes = ((colmena.lib.makeHive self.colmena).introspect (x: x)).nodes; + microvmNodes = + nixpkgs.lib.concatMapAttrs ( + nodeName: nodeAttrs: + nixpkgs.lib.mapAttrs' + (n: nixpkgs.lib.nameValuePair "${nodeName}-microvm-${n}") + (self.colmenaNodes.${nodeName}.config.microvm.vms or {}) + ) + self.colmenaNodes; + nodes = self.colmenaNodes // self.microvmNodes; # Collect installer packages inherit diff --git a/hosts/common/core/default.nix b/hosts/common/core/default.nix index 5471744..09667f3 100644 --- a/hosts/common/core/default.nix +++ b/hosts/common/core/default.nix @@ -11,6 +11,7 @@ ./xdg.nix ../../../modules/wireguard.nix + ../../../modules/microvms.nix ]; home-manager = { diff --git a/hosts/common/core/system.nix b/hosts/common/core/system.nix index 0997b7f..ade2851 100644 --- a/hosts/common/core/system.nix +++ b/hosts/common/core/system.nix @@ -2,6 +2,7 @@ inputs, lib, nodeName, + nodePath, ... }: { # IP address math library @@ -30,7 +31,7 @@ # current system due to yubikey availability. forceRekeyOnSystem = builtins.extraBuiltins.unsafeCurrentSystem; hostPubkey = let - pubkeyPath = ../.. + "/${nodeName}/secrets/host.pub"; + pubkeyPath = "${nodePath}/secrets/host.pub"; in lib.mkIf (lib.pathExists pubkeyPath || lib.trace "Missing pubkey for ${nodeName}: ${toString pubkeyPath} not found, using dummy replacement key for now." false) pubkeyPath; diff --git a/hosts/ward/default.nix b/hosts/ward/default.nix index 094ac0b..7c5c2f5 100644 --- a/hosts/ward/default.nix +++ b/hosts/ward/default.nix @@ -2,7 +2,6 @@ config, inputs, lib, - microvm, nixos-hardware, pkgs, ... @@ -11,8 +10,6 @@ nixos-hardware.common-cpu-intel nixos-hardware.common-pc-ssd - microvm.host - ../common/core ../common/hardware/intel.nix ../common/hardware/physical.nix @@ -28,21 +25,7 @@ boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"]; - microvm.vms = { - test = let - node = - (import ../../nix/generate-node.nix inputs) - "ward-microvm-test" { - system = "x86_64-linux"; - config = ./microvms/test; - }; - in { - inherit (node) pkgs specialArgs; - config = { - inherit (node) imports; - }; - }; - }; + extra.microvms.test.system = "x86_64-linux"; #services.authelia.instances.main = { # enable = true; diff --git a/hosts/ward/microvms/test/default.nix b/hosts/ward/microvms/test/default.nix index 7d68ab9..a3bd2eb 100644 --- a/hosts/ward/microvms/test/default.nix +++ b/hosts/ward/microvms/test/default.nix @@ -8,8 +8,6 @@ ... }: { imports = [ - microvm.microvm - ../../../common/core ../../../../users/root diff --git a/modules/microvms.nix b/modules/microvms.nix new file mode 100644 index 0000000..9dd8635 --- /dev/null +++ b/modules/microvms.nix @@ -0,0 +1,78 @@ +{ + inputs, + config, + lib, + nodeName, + nodePath, + microvm, + pkgs, + ... +}: let + inherit + (lib) + mapAttrs + mdDoc + mkDefault + mkForce + mkIf + mkOption + types + ; + + cfg = config.extra.microvms; + + defineMicrovm = vmName: vmCfg: let + node = + (import ../nix/generate-node.nix inputs) + "${nodeName}-microvm-${vmName}" { + inherit (vmCfg) system; + config = nodePath + "/microvms/${vmName}"; + }; + in { + inherit (node) pkgs specialArgs; + config = { + imports = [microvm.microvm] ++ node.imports; + + microvm = { + hypervisor = mkDefault "cloud-hypervisor"; + + # Share the nix-store of the host + shares = [ + { + source = "/nix/store"; + mountPoint = "/nix/.ro-store"; + tag = "ro-store"; + proto = "virtiofs"; + } + ]; + }; + + # TODO change once microvms are compatible with stage-1 systemd + boot.initrd.systemd.enable = mkForce false; + }; + }; +in { + imports = [microvm.host]; + + options.extra.microvms = mkOption { + default = {}; + description = "Provides a base configuration for MicroVMs."; + type = types.attrsOf (types.submodule { + options = { + system = mkOption { + type = types.str; + description = mdDoc "The system that this microvm should use"; + }; + }; + }); + }; + + config = { + microvm = { + host.enable = cfg != {}; + declarativeUpdates = true; + restartIfChanged = true; + vms = mkIf (cfg != {}) (mapAttrs defineMicrovm cfg); + }; + }; +} diff --git a/nix/generate-node.nix b/nix/generate-node.nix index a7c2ca9..167aaf0 100644 --- a/nix/generate-node.nix +++ b/nix/generate-node.nix @@ -14,21 +14,22 @@ } @ inputs: let inherit (nixpkgs.lib) optionals; in - nodeName: nodeMeta: { + nodeName: nodeMeta: let + nodePath = nodeMeta.config or (../hosts + "/${nodeName}"); + in { inherit (nodeMeta) system; pkgs = self.pkgs.${nodeMeta.system}; specialArgs = { inherit (nixpkgs) lib; inherit (self) extraLib nodes stateVersion; - inherit inputs; - inherit nodeName; + inherit inputs nodeName nodePath; secrets = self.secrets.content; - nodeSecrets = self.secrets.content.nodes.${nodeName}; + nodeSecrets = self.secrets.content.nodes.${nodeName} or {}; nixos-hardware = nixos-hardware.nixosModules; microvm = microvm.nixosModules; }; imports = [ - (nodeMeta.config or (../hosts + "/${nodeName}")) + nodePath # default module agenix.nixosModules.default agenix-rekey.nixosModules.default disko.nixosModules.disko