nixos/README.md: relax the requirement of providing option defaults (#334509)
[NixPkgs.git] / nixos / maintainers / scripts / ec2 / amazon-image.nix
blobd5b23d8a65f66f2a1e32115f7dafcf7edc28ae46
2   config,
3   lib,
4   pkgs,
5   ...
6 }:
8 let
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";
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   ];
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}" ];
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     };
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   };
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 (3 * 1024);
87   config.virtualisation.diskSizeAutoSupported = !config.ec2.zfs.enable;
89   config.system.nixos.tags = [ "amazon" ];
90   config.system.build.image = config.system.build.amazonImage;
91   config.image.extension = cfg.format;
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       '';
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;
118         includeChannel = true;
120         bootSize = 1000; # 1G is the minimum EBS volume
122         rootSize = config.virtualisation.diskSize;
123         rootPoolProperties = {
124           ashift = 12;
125           autoexpand = "on";
126         };
128         datasets = config.ec2.zfs.datasets;
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"
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
142           ${pkgs.jq}/bin/jq -n \
143             --arg system_label ${lib.escapeShellArg config.system.nixos.label} \
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_label
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       };
162       extBuilder = import ../../../lib/make-disk-image.nix {
163         inherit
164           lib
165           config
166           configFile
167           pkgs
168           ;
170         inherit (cfg) contents format;
171         inherit (config.image) baseName;
172         name = config.image.baseName;
174         fsType = "ext4";
175         partitionTableType = if config.ec2.efi then "efi" else "legacy+gpt";
177         inherit (config.virtualisation) diskSize;
179         postVM = ''
180            mkdir -p $out/nix-support
181            echo "file ${cfg.format} $diskImage" >> $out/nix-support/hydra-build-products
183           ${pkgs.jq}/bin/jq -n \
184             --arg system_label ${lib.escapeShellArg config.system.nixos.label} \
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_label
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;
203   meta.maintainers = with lib.maintainers; [ arianvp ];