55 config
66
77, # The size of the disk, in megabytes.
8- diskSize
8+ # if "auto" size is calculated based on the contents copied to it and
9+ # additionalSpace is taken into account.
10+ diskSize ? "auto"
911
10- # The files and directories to be placed in the target file system.
12+ , # additional disk space to be added to the image if diskSize "auto"
13+ # is used
14+ additionalSpace ? "512M"
15+
16+ , # size of the boot partition, is only used if partitionTableType is
17+ # either "efi" or "hybrid"
18+ bootSize ? "256M"
19+
20+ , # The files and directories to be placed in the target file system.
1121 # This is a list of attribute sets {source, target} where `source'
1222 # is the file system object (regular file or directory) to be
1323 # grafted in the file system at path `target'.
14- , contents ? [ ]
24+ contents ? [ ]
1525
1626, # Type of partition table to use; either "legacy", "efi", or "none".
1727 # For "efi" images, the GPT partition table is used and a mandatory ESP
1828 # partition of reasonable size is created in addition to the root partition.
19- # If `installBootLoader` is true, GRUB will be installed in EFI mode.
2029 # For "legacy", the msdos partition table is used and a single large root
21- # partition is created. If `installBootLoader` is true, GRUB will be
22- # installed in legacy mode.
30+ # partition is created.
31+ # For "hybrid", the GPT partition table is used and a mandatory ESP
32+ # partition of reasonable size is created in addition to the root partition.
33+ # Also a legacy MBR will be present.
2334 # For "none", no partition table is created. Enabling `installBootLoader`
2435 # most likely fails as GRUB will probably refuse to install.
2536 partitionTableType ? "legacy"
4354 format ? "raw"
4455} :
4556
46- assert partitionTableType == "legacy" || partitionTableType == "efi" || partitionTableType == "none" ;
57+ assert partitionTableType == "legacy" || partitionTableType == "efi" || partitionTableType == "hybrid" || partitionTableType == " none";
4758# We use -E offset=X below, which is only supported by e2fsprogs
4859assert partitionTableType != "none" -> fsType == "ext4" ;
4960
@@ -65,6 +76,7 @@ let format' = format; in let
6576 rootPartition = { # switch-case
6677 legacy = "1" ;
6778 efi = "2" ;
79+ hybrid = "3" ;
6880 } . ${ partitionTableType } ;
6981
7082 partitionDiskScript = { # switch-case
@@ -76,9 +88,18 @@ let format' = format; in let
7688 efi = ''
7789 parted --script $diskImage -- \
7890 mklabel gpt \
79- mkpart ESP fat32 8MiB 256MiB \
91+ mkpart ESP fat32 8MiB ${ bootSize } \
8092 set 1 boot on \
81- mkpart primary ext4 256MiB -1
93+ mkpart primary ext4 ${ bootSize } -1
94+ '' ;
95+ hybrid = ''
96+ parted --script $diskImage -- \
97+ mklabel gpt \
98+ mkpart ESP fat32 8MiB ${ bootSize } \
99+ set 1 boot on \
100+ mkpart no-fs 0 1024KiB \
101+ set 2 bios_grub on \
102+ mkpart primary ext4 ${ bootSize } -1
82103 '' ;
83104 none = "" ;
84105 } . ${ partitionTableType } ;
@@ -129,19 +150,6 @@ let format' = format; in let
129150 }
130151
131152 mkdir $out
132- diskImage=nixos.raw
133- truncate -s ${ toString diskSize } M $diskImage
134-
135- ${ partitionDiskScript }
136-
137- ${ if partitionTableType != "none" then ''
138- # Get start & length of the root partition in sectors to $START and $SECTORS.
139- eval $(partx $diskImage -o START,SECTORS --nr ${ rootPartition } --pairs)
140-
141- mkfs.${ fsType } -F -L ${ label } $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
142- '' else ''
143- mkfs.${ fsType } -F -L ${ label } $diskImage
144- '' }
145153
146154 root="$PWD/root"
147155 mkdir -p $root
@@ -186,6 +194,31 @@ let format' = format; in let
186194 nixos-install --root $root --no-bootloader --no-root-passwd \
187195 --system ${ config . system . build . toplevel } --channel ${ channelSources } --substituters ""
188196
197+ diskImage=nixos.raw
198+
199+ ${ if diskSize == "auto" then ''
200+ ${ if partitionTableType == "efi" || partitionTableType == "hybrid" then ''
201+ additionalSpace=$(( ($(numfmt --from=iec '${ additionalSpace } ') + $(numfmt --from=iec '${ bootSize } ')) / 1000 ))
202+ '' else ''
203+ additionalSpace=$(( $(numfmt --from=iec '${ additionalSpace } ') / 1000 ))
204+ '' }
205+ diskSize=$(( $(set -- $(du -d0 $root); echo "$1") + $additionalSpace ))
206+ truncate -s "$diskSize"K $diskImage
207+ '' else ''
208+ truncate -s ${ toString diskSize } M $diskImage
209+ '' }
210+
211+ ${ partitionDiskScript }
212+
213+ ${ if partitionTableType != "none" then ''
214+ # Get start & length of the root partition in sectors to $START and $SECTORS.
215+ eval $(partx $diskImage -o START,SECTORS --nr ${ rootPartition } --pairs)
216+
217+ mkfs.${ fsType } -F -L ${ label } $diskImage -E offset=$(sectorsToBytes $START) $(sectorsToKilobytes $SECTORS)K
218+ '' else ''
219+ mkfs.${ fsType } -F -L ${ label } $diskImage
220+ '' }
221+
189222 echo "copying staging root to image..."
190223 cptofs -p ${ optionalString ( partitionTableType != "none" ) "-P ${ rootPartition } " } -t ${ fsType } -i $diskImage $root/* /
191224 '' ;
@@ -219,7 +252,7 @@ in pkgs.vmTools.runInLinuxVM (
219252
220253 # Create the ESP and mount it. Unlike e2fsprogs, mkfs.vfat doesn't support an
221254 # '-E offset=X' option, so we can't do this outside the VM.
222- ${ optionalString ( partitionTableType == "efi" ) ''
255+ ${ optionalString ( partitionTableType == "efi" || partitionTableType == "hybrid" ) ''
223256 mkdir -p /mnt/boot
224257 mkfs.vfat -n ESP /dev/vda1
225258 mount /dev/vda1 /mnt/boot
0 commit comments