Compare commits
	
		
			2 Commits
		
	
	
		
			1f9fbd87ac
			...
			1c9fa418b3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 1c9fa418b3 | |||
| 8c4dc9cb74 | 
| @ -100,7 +100,5 @@ | |||||||
|   security.acme.defaults.email = "zuckerberg@neet.dev"; |   security.acme.defaults.email = "zuckerberg@neet.dev"; | ||||||
| 
 | 
 | ||||||
|   # Enable Desktop Environment if this is a PC (machine role is "personal") |   # Enable Desktop Environment if this is a PC (machine role is "personal") | ||||||
|   de.enable = ( |   de.enable = lib.mkDefault (config.thisMachine.hasRole."personal"); | ||||||
|     builtins.elem config.networking.hostName config.machines.roles.personal |  | ||||||
|   ); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -5,6 +5,90 @@ | |||||||
| 
 | 
 | ||||||
| let | let | ||||||
|   machines = config.machines.hosts; |   machines = config.machines.hosts; | ||||||
|  | 
 | ||||||
|  |   hostOptionsSubmoduleType = lib.types.submodule { | ||||||
|  |     options = { | ||||||
|  |       hostNames = lib.mkOption { | ||||||
|  |         type = lib.types.listOf lib.types.str; | ||||||
|  |         description = '' | ||||||
|  |           List of hostnames for this machine. The first one is the default so it is the target of deployments. | ||||||
|  |           Used for automatically trusting hosts for ssh connections. | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |       arch = lib.mkOption { | ||||||
|  |         type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ]; | ||||||
|  |         description = '' | ||||||
|  |           The architecture of this machine. | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |       systemRoles = lib.mkOption { | ||||||
|  |         type = lib.types.listOf lib.types.str; # TODO: maybe use an enum? | ||||||
|  |         description = '' | ||||||
|  |           The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info) | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |       hostKey = lib.mkOption { | ||||||
|  |         type = lib.types.str; | ||||||
|  |         description = '' | ||||||
|  |           The system ssh host key of this machine. Used for automatically trusting hosts for ssh connections | ||||||
|  |           and for decrypting secrets with agenix. | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |       remoteUnlock = lib.mkOption { | ||||||
|  |         default = null; | ||||||
|  |         type = lib.types.nullOr (lib.types.submodule { | ||||||
|  |           options = { | ||||||
|  | 
 | ||||||
|  |             hostKey = lib.mkOption { | ||||||
|  |               type = lib.types.str; | ||||||
|  |               description = '' | ||||||
|  |                 The system ssh host key of this machine used for luks boot unlocking only. | ||||||
|  |               ''; | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             clearnetHost = lib.mkOption { | ||||||
|  |               default = null; | ||||||
|  |               type = lib.types.nullOr lib.types.str; | ||||||
|  |               description = '' | ||||||
|  |                 The hostname resolvable over clearnet used to luks boot unlock this machine | ||||||
|  |               ''; | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |             onionHost = lib.mkOption { | ||||||
|  |               default = null; | ||||||
|  |               type = lib.types.nullOr lib.types.str; | ||||||
|  |               description = '' | ||||||
|  |                 The hostname resolvable over tor used to luks boot unlock this machine | ||||||
|  |               ''; | ||||||
|  |             }; | ||||||
|  | 
 | ||||||
|  |           }; | ||||||
|  |         }); | ||||||
|  |       }; | ||||||
|  |       userKeys = lib.mkOption { | ||||||
|  |         default = [ ]; | ||||||
|  |         type = lib.types.listOf lib.types.str; | ||||||
|  |         description = '' | ||||||
|  |           The list of user keys. Each key here can be used to log into all other systems as `googlebot`. | ||||||
|  | 
 | ||||||
|  |           TODO: consider auto populating other programs that use ssh keys such as gitea | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |       deployKeys = lib.mkOption { | ||||||
|  |         default = [ ]; | ||||||
|  |         type = lib.types.listOf lib.types.str; | ||||||
|  |         description = '' | ||||||
|  |           The list of deployment keys. Each key here can be used to log into all other systems as `root`. | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |       configurationPath = lib.mkOption { | ||||||
|  |         type = lib.types.path; | ||||||
|  |         description = '' | ||||||
|  |           The path to this machine's configuration directory. | ||||||
|  |         ''; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
| in | in | ||||||
| { | { | ||||||
|   imports = [ |   imports = [ | ||||||
| @ -13,104 +97,16 @@ in | |||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   options.machines = { |   options.machines = { | ||||||
| 
 |  | ||||||
|     hosts = lib.mkOption { |     hosts = lib.mkOption { | ||||||
|       type = lib.types.attrsOf |       type = lib.types.attrsOf hostOptionsSubmoduleType; | ||||||
|         (lib.types.submodule { |  | ||||||
|           options = { |  | ||||||
| 
 |  | ||||||
|             hostNames = lib.mkOption { |  | ||||||
|               type = lib.types.listOf lib.types.str; |  | ||||||
|               description = '' |  | ||||||
|                 List of hostnames for this machine. The first one is the default so it is the target of deployments. |  | ||||||
|                 Used for automatically trusting hosts for ssh connections. |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             arch = lib.mkOption { |  | ||||||
|               type = lib.types.enum [ "x86_64-linux" "aarch64-linux" ]; |  | ||||||
|               description = '' |  | ||||||
|                 The architecture of this machine. |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             systemRoles = lib.mkOption { |  | ||||||
|               type = lib.types.listOf lib.types.str; # TODO: maybe use an enum? |  | ||||||
|               description = '' |  | ||||||
|                 The set of roles this machine holds. Affects secrets available. (TODO add service config as well using this info) |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             hostKey = lib.mkOption { |  | ||||||
|               type = lib.types.str; |  | ||||||
|               description = '' |  | ||||||
|                 The system ssh host key of this machine. Used for automatically trusting hosts for ssh connections |  | ||||||
|                 and for decrypting secrets with agenix. |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             remoteUnlock = lib.mkOption { |  | ||||||
|               default = null; |  | ||||||
|               type = lib.types.nullOr (lib.types.submodule { |  | ||||||
|                 options = { |  | ||||||
| 
 |  | ||||||
|                   hostKey = lib.mkOption { |  | ||||||
|                     type = lib.types.str; |  | ||||||
|                     description = '' |  | ||||||
|                       The system ssh host key of this machine used for luks boot unlocking only. |  | ||||||
|                     ''; |  | ||||||
|                   }; |  | ||||||
| 
 |  | ||||||
|                   clearnetHost = lib.mkOption { |  | ||||||
|                     default = null; |  | ||||||
|                     type = lib.types.nullOr lib.types.str; |  | ||||||
|                     description = '' |  | ||||||
|                       The hostname resolvable over clearnet used to luks boot unlock this machine |  | ||||||
|                     ''; |  | ||||||
|                   }; |  | ||||||
| 
 |  | ||||||
|                   onionHost = lib.mkOption { |  | ||||||
|                     default = null; |  | ||||||
|                     type = lib.types.nullOr lib.types.str; |  | ||||||
|                     description = '' |  | ||||||
|                       The hostname resolvable over tor used to luks boot unlock this machine |  | ||||||
|                     ''; |  | ||||||
|                   }; |  | ||||||
| 
 |  | ||||||
|                 }; |  | ||||||
|               }); |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             userKeys = lib.mkOption { |  | ||||||
|               default = [ ]; |  | ||||||
|               type = lib.types.listOf lib.types.str; |  | ||||||
|               description = '' |  | ||||||
|                 The list of user keys. Each key here can be used to log into all other systems as `googlebot`. |  | ||||||
| 
 |  | ||||||
|                 TODO: consider auto populating other programs that use ssh keys such as gitea |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             deployKeys = lib.mkOption { |  | ||||||
|               default = [ ]; |  | ||||||
|               type = lib.types.listOf lib.types.str; |  | ||||||
|               description = '' |  | ||||||
|                 The list of deployment keys. Each key here can be used to log into all other systems as `root`. |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|             configurationPath = lib.mkOption { |  | ||||||
|               type = lib.types.path; |  | ||||||
|               description = '' |  | ||||||
|                 The path to this machine's configuration directory. |  | ||||||
|               ''; |  | ||||||
|             }; |  | ||||||
| 
 |  | ||||||
|           }; |  | ||||||
|         }); |  | ||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   options.thisMachine.config = lib.mkOption { | ||||||
|  |     # For ease of use, a direct copy of the host config from machines.hosts.${hostName} | ||||||
|  |     type = hostOptionsSubmoduleType; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   config = { |   config = { | ||||||
|     assertions = (lib.concatLists (lib.mapAttrsToList |     assertions = (lib.concatLists (lib.mapAttrsToList | ||||||
|       ( |       ( | ||||||
| @ -196,5 +192,12 @@ in | |||||||
|           builtins.map (p: { "${dirName p}" = p; }) propFiles; |           builtins.map (p: { "${dirName p}" = p; }) propFiles; | ||||||
|       in |       in | ||||||
|       properties ../../machines; |       properties ../../machines; | ||||||
|  | 
 | ||||||
|  |     # Don't try to evaluate "thisMachine" when reflecting using moduleless.nix. | ||||||
|  |     # When evaluated by moduleless.nix this will fail due to networking.hostName not | ||||||
|  |     # existing. This is because moduleless.nix is not intended for reflection from the | ||||||
|  |     # perspective of a perticular machine but is instead intended for reflecting on | ||||||
|  |     # the properties of all machines as a whole system. | ||||||
|  |     thisMachine.config = config.machines.hosts.${config.networking.hostName}; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,19 +1,55 @@ | |||||||
| { config, lib, ... }: | { config, lib, ... }: | ||||||
| 
 | 
 | ||||||
| # Maps roles to their hosts | # Maps roles to their hosts. | ||||||
|  | # machines.withRole = { | ||||||
|  | #   personal = [ | ||||||
|  | #     "machine1" "machine3" | ||||||
|  | #   ]; | ||||||
|  | #   cache = [ | ||||||
|  | #     "machine2" | ||||||
|  | #   ]; | ||||||
|  | # }; | ||||||
|  | # | ||||||
|  | # A list of all possible roles | ||||||
|  | # machines.allRoles = [ | ||||||
|  | #   "personal" | ||||||
|  | #   "cache" | ||||||
|  | # ]; | ||||||
|  | # | ||||||
|  | # For each role has true or false if the current machine has that role | ||||||
|  | # thisMachine.hasRole = { | ||||||
|  | #   personal = true; | ||||||
|  | #   cache = false; | ||||||
|  | # }; | ||||||
| 
 | 
 | ||||||
| { | { | ||||||
|   options.machines.roles = lib.mkOption { |   options.machines.withRole = lib.mkOption { | ||||||
|     type = lib.types.attrsOf (lib.types.listOf lib.types.str); |     type = lib.types.attrsOf (lib.types.listOf lib.types.str); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   options.machines.allRoles = lib.mkOption { | ||||||
|  |     type = lib.types.listOf lib.types.str; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   options.thisMachine.hasRole = lib.mkOption { | ||||||
|  |     type = lib.types.attrsOf lib.types.bool; | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   config = { |   config = { | ||||||
|     machines.roles = lib.zipAttrs |     machines.withRole = lib.zipAttrs | ||||||
|       (lib.mapAttrsToList |       (lib.mapAttrsToList | ||||||
|         (host: cfg: |         (host: cfg: | ||||||
|           lib.foldl (lib.mergeAttrs) { } |           lib.foldl (lib.mergeAttrs) { } | ||||||
|             (builtins.map (role: { ${role} = host; }) |             (builtins.map (role: { ${role} = host; }) | ||||||
|               cfg.systemRoles)) |               cfg.systemRoles)) | ||||||
|         config.machines.hosts); |         config.machines.hosts); | ||||||
|  | 
 | ||||||
|  |     machines.allRoles = lib.attrNames config.machines.withRole; | ||||||
|  | 
 | ||||||
|  |     thisMachine.hasRole = lib.mapAttrs | ||||||
|  |       (role: cfg: | ||||||
|  |         builtins.elem config.networking.hostName config.machines.withRole.${role} | ||||||
|  |       ) | ||||||
|  |       config.machines.withRole; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
| @ -39,6 +39,6 @@ in | |||||||
|         builtins.map |         builtins.map | ||||||
|           (host: machines.hosts.${host}.hostKey) |           (host: machines.hosts.${host}.hostKey) | ||||||
|           hosts) |           hosts) | ||||||
|       machines.roles; |       machines.withRole; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,18 +1,14 @@ | |||||||
| { config, lib, ... }: | { config, lib, ... }: | ||||||
| 
 | 
 | ||||||
| let | let | ||||||
|   builderRole = "nix-builder"; |  | ||||||
|   builderUserName = "nix-builder"; |   builderUserName = "nix-builder"; | ||||||
| 
 | 
 | ||||||
|   machinesByRole = role: lib.filterAttrs (hostname: cfg: builtins.elem role cfg.systemRoles) config.machines.hosts; |   builderRole = "nix-builder"; | ||||||
|   otherMachinesByRole = role: lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) (machinesByRole role); |   builders = config.machines.withRole.${builderRole}; | ||||||
|   thisMachineHasRole = role: builtins.hasAttr config.networking.hostName (machinesByRole role); |   thisMachineIsABuilder = config.thisMachine.hasRole.${builderRole}; | ||||||
| 
 |  | ||||||
|   builders = machinesByRole builderRole; |  | ||||||
|   thisMachineIsABuilder = thisMachineHasRole builderRole; |  | ||||||
| 
 | 
 | ||||||
|   # builders don't include themselves as a remote builder |   # builders don't include themselves as a remote builder | ||||||
|   otherBuilders = lib.filterAttrs (hostname: cfg: hostname != config.networking.hostName) builders; |   otherBuilders = lib.filter (hostname: hostname != config.networking.hostName) builders; | ||||||
| in | in | ||||||
| lib.mkMerge [ | lib.mkMerge [ | ||||||
|   # configure builder |   # configure builder | ||||||
| @ -40,9 +36,9 @@ lib.mkMerge [ | |||||||
|     nix.distributedBuilds = true; |     nix.distributedBuilds = true; | ||||||
| 
 | 
 | ||||||
|     nix.buildMachines = builtins.map |     nix.buildMachines = builtins.map | ||||||
|       (builderCfg: { |       (builderHostname: { | ||||||
|         hostName = builtins.elemAt builderCfg.hostNames 0; |         hostName = builderHostname; | ||||||
|         system = builderCfg.arch; |         system = config.machines.hosts.${builderHostname}.arch; | ||||||
|         protocol = "ssh-ng"; |         protocol = "ssh-ng"; | ||||||
|         sshUser = builderUserName; |         sshUser = builderUserName; | ||||||
|         sshKey = "/etc/ssh/ssh_host_ed25519_key"; |         sshKey = "/etc/ssh/ssh_host_ed25519_key"; | ||||||
| @ -50,7 +46,7 @@ lib.mkMerge [ | |||||||
|         speedFactor = 10; |         speedFactor = 10; | ||||||
|         supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; |         supportedFeatures = [ "nixos-test" "benchmark" "big-parallel" "kvm" ]; | ||||||
|       }) |       }) | ||||||
|       (builtins.attrValues otherBuilders); |       otherBuilders; | ||||||
| 
 | 
 | ||||||
|     # It is very likely that the builder's internet is faster or just as fast |     # It is very likely that the builder's internet is faster or just as fast | ||||||
|     nix.extraOptions = '' |     nix.extraOptions = '' | ||||||
|  | |||||||
| @ -9,10 +9,7 @@ | |||||||
| # TODO: skipping running inside of nixos container for now because of issues getting docker/podman running | # TODO: skipping running inside of nixos container for now because of issues getting docker/podman running | ||||||
| 
 | 
 | ||||||
| let | let | ||||||
|   runnerRole = "gitea-actions-runner"; |   thisMachineIsARunner = config.thisMachine.hasRole."gitea-actions-runner"; | ||||||
|   runners = config.machines.roles.${runnerRole}; |  | ||||||
|   thisMachineIsARunner = builtins.elem config.networking.hostName runners; |  | ||||||
| 
 |  | ||||||
|   containerName = "gitea-runner"; |   containerName = "gitea-runner"; | ||||||
| in | in | ||||||
| { | { | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								flake.nix
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								flake.nix
									
									
									
									
									
								
							| @ -84,13 +84,11 @@ | |||||||
| 
 | 
 | ||||||
|   outputs = { self, nixpkgs, ... }@inputs: |   outputs = { self, nixpkgs, ... }@inputs: | ||||||
|     let |     let | ||||||
|       machines = (import ./common/machine-info/moduleless.nix |       machineHosts = (import ./common/machine-info/moduleless.nix | ||||||
|         { |         { | ||||||
|           inherit nixpkgs; |           inherit nixpkgs; | ||||||
|           assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix"; |           assertionsModule = "${nixpkgs}/nixos/modules/misc/assertions.nix"; | ||||||
|         }).machines; |         }).machines.hosts; | ||||||
|       machineHosts = machines.hosts; |  | ||||||
|       machineRoles = machines.roles; |  | ||||||
|     in |     in | ||||||
|     { |     { | ||||||
|       nixosConfigurations = |       nixosConfigurations = | ||||||
| @ -115,10 +113,7 @@ | |||||||
| 
 | 
 | ||||||
|                 home-manager.useGlobalPkgs = true; |                 home-manager.useGlobalPkgs = true; | ||||||
|                 home-manager.useUserPackages = true; |                 home-manager.useUserPackages = true; | ||||||
|                 home-manager.users.googlebot = import ./home/googlebot.nix { |                 home-manager.users.googlebot = import ./home/googlebot.nix; | ||||||
|                   inherit hostname; |  | ||||||
|                   inherit machineRoles; |  | ||||||
|                 }; |  | ||||||
|               }; |               }; | ||||||
| 
 | 
 | ||||||
|               # because nixos specialArgs doesn't work for containers... need to pass in inputs a different way |               # because nixos specialArgs doesn't work for containers... need to pass in inputs a different way | ||||||
|  | |||||||
| @ -1,9 +1,8 @@ | |||||||
| { hostname, machineRoles }: | { config, lib, pkgs, osConfig, ... }: | ||||||
| { config, lib, pkgs, ... }: |  | ||||||
| 
 | 
 | ||||||
| let | let | ||||||
|   # Check if the current machine has the role "personal" |   # Check if the current machine has the role "personal" | ||||||
|   thisMachineIsPersonal = builtins.elem hostname machineRoles.personal; |   thisMachineIsPersonal = osConfig.thisMachine.hasRole."personal"; | ||||||
| in | in | ||||||
| { | { | ||||||
|   home.username = "googlebot"; |   home.username = "googlebot"; | ||||||
|  | |||||||
| @ -1,6 +1,7 @@ | |||||||
| { | { | ||||||
|   hostNames = [ |   hostNames = [ | ||||||
|     "s0" |     "s0" | ||||||
|  |     "s0.neet.dev" | ||||||
|   ]; |   ]; | ||||||
| 
 | 
 | ||||||
|   arch = "x86_64-linux"; |   arch = "x86_64-linux"; | ||||||
| @ -19,6 +20,8 @@ | |||||||
| 
 | 
 | ||||||
|   remoteUnlock = { |   remoteUnlock = { | ||||||
|     hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH"; |     hostKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFNiceeFMos5ZXcYem4yFxh8PiZNNnuvhlyLbQLrgIZH"; | ||||||
|  | 
 | ||||||
|  |     clearnetHost = "192.168.1.2"; | ||||||
|     onionHost = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion"; |     onionHost = "r3zvf7f2ppaeithzswigma46pajt3hqytmkg3rshgknbl3jbni455fqd.onion"; | ||||||
|   }; |   }; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user