{ inputs, lib, ... }: let inherit (builtins) readDir readFile fromJSON; inherit (lib) attrNames mkOption evalModules filterAttrs ; inherit (lib.attrsets) genAttrs; sources = import ../../npins; ## Given a machine's name and whether it is a test VM, make a resource module, ## except for its missing provider. (Depending on the use of that resource, we ## will provide a different one.) makeResourceModule = { vmName, isTestVm }: { imports = [ ./common/resource.nix ] ++ ( if isTestVm then [ ./test-machines/${vmName} { nixos.module.users.users.root.openssh.authorizedKeys.keys = [ # allow our panel vm access to the test machines (import ../keys).panel ]; } ] else [ ./machines/${vmName} ] ); fediversityVm.name = vmName; }; ## Given a list of machine names, make a deployment with those machines' ## configurations as resources. makeDeployment = vmNames: { providers, ... }: { providers.local = inputs.nixops4.modules.nixops4Provider.local; resources = genAttrs vmNames (vmName: { type = providers.local.exec; imports = [ inputs.nixops4-nixos.modules.nixops4Resource.nixos (makeResourceModule { inherit vmName; isTestVm = false; }) ]; }); }; makeDeployment' = vmName: makeDeployment [ vmName ]; ## Given an attrset of test configurations (key = test machine name, value = ## NixOS configuration module), make a deployment with those machines' ## configurations as resources. makeTestDeployment = (import ../deployment) { inherit lib; inherit (inputs) nixops4 nixops4-nixos; fediversity = import ../services/fediversity; } { garageConfigurationResource = makeResourceModule { vmName = "test01"; isTestVm = true; }; mastodonConfigurationResource = makeResourceModule { vmName = "test06"; # somehow `test02` has a problem - use test06 instead isTestVm = true; }; peertubeConfigurationResource = makeResourceModule { vmName = "test05"; isTestVm = true; }; pixelfedConfigurationResource = makeResourceModule { vmName = "test04"; isTestVm = true; }; }; nixops4ResourceNixosMockOptions = { ## NOTE: We allow the use of a few options from ## `nixops4-nixos.modules.nixops4Resource.nixos` such that we can ## reuse modules that make use of them. ## ## REVIEW: We can probably do much better and cleaner. On the other hand, ## this is only needed to expose NixOS configurations for provisioning ## purposes, and eventually all of this should be handled by NixOps4. options = { nixos.module = mkOption { }; # NOTE: not just `nixos` otherwise merging will go wrong nixpkgs = mkOption { }; ssh = mkOption { }; }; }; makeResourceConfig = vm: (evalModules { modules = [ nixops4ResourceNixosMockOptions (makeResourceModule vm) ]; }).config; ## Given a VM name, make a NixOS configuration for this machine. makeConfiguration = isTestVm: vmName: let inherit (sources) nixpkgs; in import "${nixpkgs}/nixos" { modules = [ (makeResourceConfig { inherit vmName isTestVm; }).nixos.module ]; }; makeVmOptions = isTestVm: vmName: { inherit ((makeResourceConfig { inherit vmName isTestVm; }).fediversityVm) proxmox vmId description sockets cores memory diskSize hostPublicKey unsafeHostPrivateKey ; }; listSubdirectories = path: attrNames (filterAttrs (_: type: type == "directory") (readDir path)); machines = listSubdirectories ./machines; testMachines = listSubdirectories ./test-machines; in { ## - Each normal or test machine gets a NixOS configuration. ## - Each normal or test machine gets a VM options entry. ## - Each normal machine gets a deployment. ## - We add a “default” deployment with all normal machines. ## - We add a “test” deployment with all test machines. nixops4Deployments = genAttrs machines makeDeployment' // { default = makeDeployment machines; test = makeTestDeployment ( fromJSON ( let env = builtins.getEnv "DEPLOYMENT"; in if env != "" then env else builtins.trace "env var DEPLOYMENT not set, falling back to ./test-machines/configuration.json!" (readFile ./test-machines/configuration.json) ) ); }; flake.nixosConfigurations = genAttrs machines (makeConfiguration false) // genAttrs testMachines (makeConfiguration true); flake.vmOptions = genAttrs machines (makeVmOptions false) // genAttrs testMachines (makeVmOptions true); }