# GPT disk with a single HFS+ partition named VMIX. macOS mounts it natively by # name at /Volumes/VMIX (its FAT driver rejects Linux-made FAT volumes as # "damaged"; HFS+ made by mkfs.hfsplus mounts cleanly). The partition starts at # 1 MiB. Files are staged with their target names and copied in via libguestfs. # files: list of { source = ; name = "dest name"; } — directories copied recursively. { pkgs, lib, ... }: { name ? "vmix", files, size ? "64M" }: pkgs.runCommand "${name}-vmix-volume.img" { nativeBuildInputs = with pkgs; [ hfsprogs gptfdisk gnutar libguestfs-with-appliance ]; } '' mkdir stage ${lib.concatMapStringsSep "\n" (f: '' mkdir -p "$(dirname "stage/${f.name}")" cp -r --no-preserve=mode ${f.source} "stage/${f.name}" '') files} tar -C stage -cf stage.tar . truncate -s ${size} $out sgdisk -n 1:2048:0 -t 1:AF00 -c 1:VMIX $out >/dev/null FIRST=$(sgdisk -i 1 $out | sed -n 's/First sector: \([0-9]*\).*/\1/p') LAST=$(sgdisk -i 1 $out | sed -n 's/Last sector: \([0-9]*\).*/\1/p') truncate -s $(( (LAST - FIRST + 1) * 512 )) hfs.part mkfs.hfsplus -v VMIX hfs.part >/dev/null # tar-in takes a host-side tarball and unpacks it into the mounted volume guestfish -a hfs.part run : mount /dev/sda / : tar-in stage.tar / : ls / : umount / dd if=hfs.part of=$out bs=512 seek=$FIRST conv=notrunc status=none ''