at master 6.3 kB view raw
1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 inherit (lib) 10 mkOption 11 optionalString 12 types 13 versionAtLeast 14 ; 15 inherit (lib.options) literalExpression; 16 cfg = config.amazonImage; 17 amiBootMode = if config.ec2.efi then "uefi" else "legacy-bios"; 18in 19{ 20 imports = [ 21 ../../../modules/virtualisation/amazon-image.nix 22 ../../../modules/virtualisation/disk-size-option.nix 23 ../../../modules/image/file-options.nix 24 (lib.mkRenamedOptionModuleWith { 25 sinceRelease = 2411; 26 from = [ 27 "amazonImage" 28 "sizeMB" 29 ]; 30 to = [ 31 "virtualisation" 32 "diskSize" 33 ]; 34 }) 35 (lib.mkRenamedOptionModuleWith { 36 sinceRelease = 2505; 37 from = [ 38 "amazonImage" 39 "name" 40 ]; 41 to = [ 42 "image" 43 "baseName" 44 ]; 45 }) 46 ]; 47 48 # Amazon recommends setting this to the highest possible value for a good EBS 49 # experience, which prior to 4.15 was 255. 50 # https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/nvme-ebs-volumes.html#timeout-nvme-ebs-volumes 51 config.boot.kernelParams = 52 let 53 timeout = 54 if versionAtLeast config.boot.kernelPackages.kernel.version "4.15" then "4294967295" else "255"; 55 in 56 [ "nvme_core.io_timeout=${timeout}" ]; 57 58 options.amazonImage = { 59 contents = mkOption { 60 example = literalExpression '' 61 [ { source = pkgs.memtest86 + "/memtest.bin"; 62 target = "boot/memtest.bin"; 63 } 64 ] 65 ''; 66 default = [ ]; 67 description = '' 68 This option lists files to be copied to fixed locations in the 69 generated image. Glob patterns work. 70 ''; 71 }; 72 73 format = mkOption { 74 type = types.enum [ 75 "raw" 76 "qcow2" 77 "vpc" 78 ]; 79 default = "vpc"; 80 description = "The image format to output"; 81 }; 82 }; 83 84 # Use a priority just below mkOptionDefault (1500) instead of lib.mkDefault 85 # to avoid breaking existing configs using that. 86 config.virtualisation.diskSize = lib.mkOverride 1490 (4 * 1024); 87 config.virtualisation.diskSizeAutoSupported = !config.ec2.zfs.enable; 88 89 config.system.nixos.tags = [ "amazon" ]; 90 config.system.build.image = config.system.build.amazonImage; 91 config.image.extension = if cfg.format == "vpc" then "vhd" else cfg.format; 92 93 config.system.build.amazonImage = 94 let 95 configFile = pkgs.writeText "configuration.nix" '' 96 { modulesPath, ... }: { 97 imports = [ "''${modulesPath}/virtualisation/amazon-image.nix" ]; 98 ${optionalString config.ec2.efi '' 99 ec2.efi = true; 100 ''} 101 ${optionalString config.ec2.zfs.enable '' 102 ec2.zfs.enable = true; 103 networking.hostId = "${config.networking.hostId}"; 104 ''} 105 } 106 ''; 107 108 zfsBuilder = import ../../../lib/make-multi-disk-zfs-image.nix { 109 inherit 110 lib 111 config 112 configFile 113 pkgs 114 ; 115 inherit (cfg) contents format; 116 name = config.image.baseName; 117 118 includeChannel = true; 119 120 bootSize = 1000; # 1G is the minimum EBS volume 121 122 rootSize = config.virtualisation.diskSize; 123 rootPoolProperties = { 124 ashift = 12; 125 autoexpand = "on"; 126 }; 127 128 datasets = config.ec2.zfs.datasets; 129 130 postVM = '' 131 extension=''${rootDiskImage##*.} 132 friendlyName=$out/${config.image.baseName} 133 rootDisk="$friendlyName.root.$extension" 134 bootDisk="$friendlyName.boot.$extension" 135 mv "$rootDiskImage" "$rootDisk" 136 mv "$bootDiskImage" "$bootDisk" 137 138 mkdir -p $out/nix-support 139 echo "file ${cfg.format} $bootDisk" >> $out/nix-support/hydra-build-products 140 echo "file ${cfg.format} $rootDisk" >> $out/nix-support/hydra-build-products 141 142 ${pkgs.jq}/bin/jq -n \ 143 --arg system_version ${lib.escapeShellArg config.system.nixos.version} \ 144 --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \ 145 --arg root_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$rootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ 146 --arg boot_logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$bootDisk" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ 147 --arg boot_mode "${amiBootMode}" \ 148 --arg root "$rootDisk" \ 149 --arg boot "$bootDisk" \ 150 '{} 151 | .label = $system_version 152 | .boot_mode = $boot_mode 153 | .system = $system 154 | .disks.boot.logical_bytes = $boot_logical_bytes 155 | .disks.boot.file = $boot 156 | .disks.root.logical_bytes = $root_logical_bytes 157 | .disks.root.file = $root 158 ' > $out/nix-support/image-info.json 159 ''; 160 }; 161 162 extBuilder = import ../../../lib/make-disk-image.nix { 163 inherit 164 lib 165 config 166 configFile 167 pkgs 168 ; 169 170 inherit (cfg) contents format; 171 inherit (config.image) baseName; 172 name = config.image.baseName; 173 174 fsType = "ext4"; 175 partitionTableType = if config.ec2.efi then "efi" else "legacy+gpt"; 176 177 inherit (config.virtualisation) diskSize; 178 179 postVM = '' 180 mkdir -p $out/nix-support 181 echo "file ${cfg.format} $diskImage" >> $out/nix-support/hydra-build-products 182 183 ${pkgs.jq}/bin/jq -n \ 184 --arg system_version ${lib.escapeShellArg config.system.nixos.version} \ 185 --arg system ${lib.escapeShellArg pkgs.stdenv.hostPlatform.system} \ 186 --arg logical_bytes "$(${pkgs.qemu_kvm}/bin/qemu-img info --output json "$diskImage" | ${pkgs.jq}/bin/jq '."virtual-size"')" \ 187 --arg boot_mode "${amiBootMode}" \ 188 --arg file "$diskImage" \ 189 '{} 190 | .label = $system_version 191 | .boot_mode = $boot_mode 192 | .system = $system 193 | .logical_bytes = $logical_bytes 194 | .file = $file 195 | .disks.root.logical_bytes = $logical_bytes 196 | .disks.root.file = $file 197 ' > $out/nix-support/image-info.json 198 ''; 199 }; 200 in 201 if config.ec2.zfs.enable then zfsBuilder else extBuilder; 202 203 meta.maintainers = with lib.maintainers; [ arianvp ]; 204}