Create automatic installation ISOs (#26)
Co-authored-by: Taeer Bar-Yam <taeer.bar-yam@moduscreate.com> Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io> Reviewed-on: Fediversity/simple-nixos-fediverse#26 Co-authored-by: Nicolas “Niols” Jeannerod <nicolas.jeannerod@moduscreate.com> Co-committed-by: Nicolas “Niols” Jeannerod <nicolas.jeannerod@moduscreate.com>
This commit is contained in:
		
							parent
							
								
									7b36774b80
								
							
						
					
					
						commit
						e9b5de893d
					
				
					 10 changed files with 179 additions and 27 deletions
				
			
		
							
								
								
									
										20
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										20
									
								
								README.md
									
										
									
									
									
								
							|  | @ -46,6 +46,26 @@ NOTE: it sometimes takes a while for the services to start up, and in the meanti | ||||||
|     ```bash |     ```bash | ||||||
|     pixelfed-manage user:create --name=test --username=test --email=test@test.com --password=testtest --confirm_email=1 |     pixelfed-manage user:create --name=test --username=test --email=test@test.com --password=testtest --confirm_email=1 | ||||||
|     ``` |     ``` | ||||||
|  | # Building an installer image | ||||||
|  | 
 | ||||||
|  | Build an installer image for the desired configuration, e.g. for `peertube`: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | nix build .#installers.peertube | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | Upload the image in `./result` to Proxmox when creating a VM. | ||||||
|  | Booting the image will format the disk and install NixOS with the desired configuration. | ||||||
|  | 
 | ||||||
|  | # Deploying an updated machine configuration | ||||||
|  | 
 | ||||||
|  | > TODO: There is currently no way to specify an actual target machine by name. | ||||||
|  | 
 | ||||||
|  | Assuming you have SSH configuration with access to the remote `root` user stored for a machine called e.g. `peertube`, deploy the configuration by the same name: | ||||||
|  | 
 | ||||||
|  | ```bash | ||||||
|  | nix run .#deploy.peertube | ||||||
|  | ``` | ||||||
| 
 | 
 | ||||||
| ## debugging notes | ## debugging notes | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										13
									
								
								deploy.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								deploy.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | ||||||
|  | { writeShellApplication }: | ||||||
|  | name: config: | ||||||
|  | writeShellApplication { | ||||||
|  |   name = "deploy"; | ||||||
|  |   text = '' | ||||||
|  |     result="$(nix build --print-out-paths ${./.}#nixosConfigurations#${name} --eval-store auto --store ssh-ng://${name})" | ||||||
|  |     # shellcheck disable=SC2087 | ||||||
|  |     ssh ${name} << EOF | ||||||
|  |     nix-env -p /nix/var/nix/profiles/system --set "$result" | ||||||
|  |     "$result"/bin/switch-to-configuration switch | ||||||
|  |     EOF | ||||||
|  |   ''; | ||||||
|  | }  | ||||||
							
								
								
									
										36
									
								
								disk-layout.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								disk-layout.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | { ... }: | ||||||
|  | { | ||||||
|  |   disko.devices.disk.main = { | ||||||
|  |     device = "/dev/sda"; | ||||||
|  |     type = "disk"; | ||||||
|  |     content = { | ||||||
|  |       type = "gpt"; | ||||||
|  |       partitions = { | ||||||
|  |         MBR = { | ||||||
|  |           priority = 0; | ||||||
|  |           size = "1M"; | ||||||
|  |           type = "EF02"; | ||||||
|  |         }; | ||||||
|  |         ESP = { | ||||||
|  |           priority = 1; | ||||||
|  |           size = "500M"; | ||||||
|  |           type = "EF00"; | ||||||
|  |           content = { | ||||||
|  |             type = "filesystem"; | ||||||
|  |             format = "vfat"; | ||||||
|  |             mountpoint = "/boot"; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |         root = { | ||||||
|  |           priority = 2; | ||||||
|  |           size = "100%"; | ||||||
|  |           content = { | ||||||
|  |             type = "filesystem"; | ||||||
|  |             format = "ext4"; | ||||||
|  |             mountpoint = "/"; | ||||||
|  |           }; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |     }; | ||||||
|  |   }; | ||||||
|  | } | ||||||
							
								
								
									
										53
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										53
									
								
								flake.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1,17 +1,35 @@ | ||||||
| { | { | ||||||
|   "nodes": { |   "nodes": { | ||||||
|     "nixpkgs": { |     "disko": { | ||||||
|  |       "inputs": { | ||||||
|  |         "nixpkgs": "nixpkgs" | ||||||
|  |       }, | ||||||
|       "locked": { |       "locked": { | ||||||
|         "lastModified": 1723726852, |         "lastModified": 1727347829, | ||||||
|         "narHash": "sha256-lRzlx4fPRtzA+dgz9Rh4WK5yAW3TsAXx335DQqxY2XY=", |         "narHash": "sha256-y7cW6TjJKy+tu7efxeWI6lyg4VVx/9whx+OmrhmRShU=", | ||||||
|         "owner": "radvendii", |         "owner": "nix-community", | ||||||
|         "repo": "nixpkgs", |         "repo": "disko", | ||||||
|         "rev": "9286249a1673cf5b14a4793e22dd44b70cb69a0d", |         "rev": "1879e48907c14a70302ff5d0539c3b9b6f97feaa", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       }, |       }, | ||||||
|       "original": { |       "original": { | ||||||
|         "owner": "radvendii", |         "owner": "nix-community", | ||||||
|         "ref": "nixos_rebuild_tests", |         "repo": "disko", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|  |     "nixpkgs": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1725194671, | ||||||
|  |         "narHash": "sha256-tLGCFEFTB5TaOKkpfw3iYT9dnk4awTP/q4w+ROpMfuw=", | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "rev": "b833ff01a0d694b910daca6e2ff4a3f26dee478c", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "NixOS", | ||||||
|  |         "ref": "nixpkgs-unstable", | ||||||
|         "repo": "nixpkgs", |         "repo": "nixpkgs", | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|  | @ -31,6 +49,22 @@ | ||||||
|         "type": "github" |         "type": "github" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "nixpkgs_2": { | ||||||
|  |       "locked": { | ||||||
|  |         "lastModified": 1723726852, | ||||||
|  |         "narHash": "sha256-lRzlx4fPRtzA+dgz9Rh4WK5yAW3TsAXx335DQqxY2XY=", | ||||||
|  |         "owner": "radvendii", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "rev": "9286249a1673cf5b14a4793e22dd44b70cb69a0d", | ||||||
|  |         "type": "github" | ||||||
|  |       }, | ||||||
|  |       "original": { | ||||||
|  |         "owner": "radvendii", | ||||||
|  |         "ref": "nixos_rebuild_tests", | ||||||
|  |         "repo": "nixpkgs", | ||||||
|  |         "type": "github" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "pixelfed": { |     "pixelfed": { | ||||||
|       "flake": false, |       "flake": false, | ||||||
|       "locked": { |       "locked": { | ||||||
|  | @ -50,7 +84,8 @@ | ||||||
|     }, |     }, | ||||||
|     "root": { |     "root": { | ||||||
|       "inputs": { |       "inputs": { | ||||||
|         "nixpkgs": "nixpkgs", |         "disko": "disko", | ||||||
|  |         "nixpkgs": "nixpkgs_2", | ||||||
|         "nixpkgs-latest": "nixpkgs-latest", |         "nixpkgs-latest": "nixpkgs-latest", | ||||||
|         "pixelfed": "pixelfed" |         "pixelfed": "pixelfed" | ||||||
|       } |       } | ||||||
|  |  | ||||||
							
								
								
									
										27
									
								
								flake.nix
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								flake.nix
									
										
									
									
									
								
							|  | @ -6,11 +6,13 @@ | ||||||
|       url = "github:pixelfed/pixelfed?ref=v0.12.3"; |       url = "github:pixelfed/pixelfed?ref=v0.12.3"; | ||||||
|       flake = false; |       flake = false; | ||||||
|     }; |     }; | ||||||
|  |     disko.url = "github:nix-community/disko"; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   outputs = { self, nixpkgs, nixpkgs-latest, pixelfed }: |   outputs = { self, nixpkgs, nixpkgs-latest, pixelfed, disko }: | ||||||
|   let |   let | ||||||
|     system = "x86_64-linux"; |     system = "x86_64-linux"; | ||||||
|  |     lib = nixpkgs.lib; | ||||||
|     pkgs = nixpkgs.legacyPackages.${system}; |     pkgs = nixpkgs.legacyPackages.${system}; | ||||||
|     pkgsLatest = nixpkgs-latest.legacyPackages.${system}; |     pkgsLatest = nixpkgs-latest.legacyPackages.${system}; | ||||||
|     bleedingFediverseOverlay = (self: super: { |     bleedingFediverseOverlay = (self: super: { | ||||||
|  | @ -21,7 +23,6 @@ | ||||||
|       ## TODO: give mastodon, peertube the same treatment |       ## TODO: give mastodon, peertube the same treatment | ||||||
|     }); |     }); | ||||||
|   in { |   in { | ||||||
| 
 |  | ||||||
|     nixosModules = { |     nixosModules = { | ||||||
|       ## Bleeding-edge fediverse packages |       ## Bleeding-edge fediverse packages | ||||||
|       bleedingFediverse = { |       bleedingFediverse = { | ||||||
|  | @ -36,12 +37,16 @@ | ||||||
|       mastodon-vm = import ./vm/mastodon-vm.nix; |       mastodon-vm = import ./vm/mastodon-vm.nix; | ||||||
|       peertube-vm = import ./vm/peertube-vm.nix; |       peertube-vm = import ./vm/peertube-vm.nix; | ||||||
|       pixelfed-vm = import ./vm/pixelfed-vm.nix; |       pixelfed-vm = import ./vm/pixelfed-vm.nix; | ||||||
|  | 
 | ||||||
|  |       disk-layout = import ./disk-layout.nix; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     nixosConfigurations = { |     nixosConfigurations = { | ||||||
|       mastodon = nixpkgs.lib.nixosSystem { |       mastodon = nixpkgs.lib.nixosSystem { | ||||||
|         inherit system; |         inherit system; | ||||||
|         modules = with self.nixosModules; [  |         modules = with self.nixosModules; [  | ||||||
|  |           disko.nixosModules.default | ||||||
|  |           disk-layout | ||||||
|           bleedingFediverse |           bleedingFediverse | ||||||
|           fediversity |           fediversity | ||||||
|           interactive-vm |           interactive-vm | ||||||
|  | @ -53,6 +58,8 @@ | ||||||
|       peertube = nixpkgs.lib.nixosSystem { |       peertube = nixpkgs.lib.nixosSystem { | ||||||
|         inherit system; |         inherit system; | ||||||
|         modules = with self.nixosModules; [ |         modules = with self.nixosModules; [ | ||||||
|  |           disko.nixosModules.default | ||||||
|  |           disk-layout | ||||||
|           bleedingFediverse |           bleedingFediverse | ||||||
|           fediversity |           fediversity | ||||||
|           interactive-vm |           interactive-vm | ||||||
|  | @ -64,6 +71,8 @@ | ||||||
|       pixelfed = nixpkgs.lib.nixosSystem { |       pixelfed = nixpkgs.lib.nixosSystem { | ||||||
|         inherit system; |         inherit system; | ||||||
|         modules = with self.nixosModules; [ |         modules = with self.nixosModules; [ | ||||||
|  |           disko.nixosModules.default | ||||||
|  |           disk-layout | ||||||
|           bleedingFediverse |           bleedingFediverse | ||||||
|           fediversity |           fediversity | ||||||
|           interactive-vm |           interactive-vm | ||||||
|  | @ -75,6 +84,8 @@ | ||||||
|       all = nixpkgs.lib.nixosSystem { |       all = nixpkgs.lib.nixosSystem { | ||||||
|         inherit system; |         inherit system; | ||||||
|         modules = with self.nixosModules; [ |         modules = with self.nixosModules; [ | ||||||
|  |           disko.nixosModules.default | ||||||
|  |           disk-layout | ||||||
|           bleedingFediverse |           bleedingFediverse | ||||||
|           fediversity |           fediversity | ||||||
|           interactive-vm |           interactive-vm | ||||||
|  | @ -86,6 +97,18 @@ | ||||||
|       }; |       }; | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|  |     installers = | ||||||
|  |       let | ||||||
|  |         installer = (import ./installer.nix) nixpkgs; | ||||||
|  |       in | ||||||
|  |       lib.mapAttrs (_: config: installer config) self.nixosConfigurations; | ||||||
|  | 
 | ||||||
|  |     deploy = | ||||||
|  |       let | ||||||
|  |         deployCommand = (pkgs.callPackage ./deploy.nix { }); | ||||||
|  |       in | ||||||
|  |       lib.mapAttrs (name: config: deployCommand name config) self.nixosConfigurations; | ||||||
|  | 
 | ||||||
|     checks.${system} = { |     checks.${system} = { | ||||||
|       mastodon-garage = import ./tests/mastodon-garage.nix { inherit pkgs self; }; |       mastodon-garage = import ./tests/mastodon-garage.nix { inherit pkgs self; }; | ||||||
|       pixelfed-garage = import ./tests/pixelfed-garage.nix { inherit pkgs self; }; |       pixelfed-garage = import ./tests/pixelfed-garage.nix { inherit pkgs self; }; | ||||||
|  |  | ||||||
							
								
								
									
										37
									
								
								installer.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								installer.nix
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | /** | ||||||
|  |   Convert a NixOS configuration to one for a minimal installer ISO | ||||||
|  | 
 | ||||||
|  |   WARNING: Running this installer will format the target disk! | ||||||
|  | */ | ||||||
|  | nixpkgs: machine: | ||||||
|  |   let | ||||||
|  |     installer = { config, pkgs, lib, ... }: | ||||||
|  |       let | ||||||
|  |         bootstrap = pkgs.writeShellApplication { | ||||||
|  |           name = "bootstrap"; | ||||||
|  |           runtimeInputs = with pkgs; [ nixos-install-tools ]; | ||||||
|  |           text = '' | ||||||
|  |             ${machine.config.system.build.diskoScript} | ||||||
|  |             nixos-install --no-root-password --no-channel-copy --system ${machine.config.system.build.toplevel} | ||||||
|  |           ''; | ||||||
|  |         }; | ||||||
|  |       in | ||||||
|  |       { | ||||||
|  |         imports = [ | ||||||
|  |           "${nixpkgs}/nixos/modules/installer/cd-dvd/installation-cd-minimal.nix" | ||||||
|  |         ]; | ||||||
|  |         nixpkgs.hostPlatform = "x86_64-linux"; | ||||||
|  |         services.getty.autologinUser = lib.mkForce "root"; | ||||||
|  |         programs.bash.loginShellInit = '' | ||||||
|  |           ${nixpkgs.lib.getExe bootstrap} | ||||||
|  |         ''; | ||||||
|  | 
 | ||||||
|  |         isoImage = { | ||||||
|  |           compressImage = false; | ||||||
|  |           squashfsCompression = "gzip -Xcompression-level 1"; | ||||||
|  |           isoName = lib.mkForce "installer.iso"; | ||||||
|  |         }; | ||||||
|  |       }; | ||||||
|  |   in | ||||||
|  |   (nixpkgs.lib.nixosSystem { modules =  [installer];}).config.system.build.isoImage | ||||||
|  |   | ||||||
|  | @ -6,10 +6,7 @@ let | ||||||
|   fedicfg = config.fediversity.internal.garage; |   fedicfg = config.fediversity.internal.garage; | ||||||
| 
 | 
 | ||||||
| in { | in { | ||||||
|   imports = [ |   imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; | ||||||
|     ../fediversity |  | ||||||
|     (modulesPath + "/virtualisation/qemu-vm.nix") |  | ||||||
|   ]; |  | ||||||
| 
 | 
 | ||||||
|   services.nginx.virtualHosts.${fedicfg.web.rootDomain} = { |   services.nginx.virtualHosts.${fedicfg.web.rootDomain} = { | ||||||
|     forceSSL = mkVMOverride false; |     forceSSL = mkVMOverride false; | ||||||
|  |  | ||||||
|  | @ -1,9 +1,6 @@ | ||||||
| { modulesPath, lib, config, ... }: { | { modulesPath, lib, config, ... }: { | ||||||
| 
 | 
 | ||||||
|   imports = [ |   imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; | ||||||
|     ../fediversity |  | ||||||
|     (modulesPath + "/virtualisation/qemu-vm.nix") |  | ||||||
|   ]; |  | ||||||
| 
 | 
 | ||||||
|   config = lib.mkMerge [ |   config = lib.mkMerge [ | ||||||
|     { |     { | ||||||
|  |  | ||||||
|  | @ -1,9 +1,6 @@ | ||||||
| { pkgs, modulesPath, ... }: { | { pkgs, modulesPath, ... }: { | ||||||
| 
 | 
 | ||||||
|   imports = [ |   imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; | ||||||
|     ../fediversity |  | ||||||
|     (modulesPath + "/virtualisation/qemu-vm.nix") |  | ||||||
|   ]; |  | ||||||
| 
 | 
 | ||||||
|   services.peertube = { |   services.peertube = { | ||||||
|     enableWebHttps = false; |     enableWebHttps = false; | ||||||
|  |  | ||||||
|  | @ -4,10 +4,7 @@ let | ||||||
|   inherit (lib) mkVMOverride; |   inherit (lib) mkVMOverride; | ||||||
| 
 | 
 | ||||||
| in { | in { | ||||||
|   imports = [ |   imports = [ (modulesPath + "/virtualisation/qemu-vm.nix") ]; | ||||||
|     ../fediversity |  | ||||||
|     (modulesPath + "/virtualisation/qemu-vm.nix") |  | ||||||
|   ]; |  | ||||||
| 
 | 
 | ||||||
|   fediversity = { |   fediversity = { | ||||||
|     enable = true; |     enable = true; | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Valentin Gagarin
							Valentin Gagarin