You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
180 lines
4.8 KiB
180 lines
4.8 KiB
{ pkgs |
|
, lib |
|
, # The NixOS configuration to be installed onto the disk image. |
|
config |
|
|
|
, # The size of the disk, in megabytes. |
|
diskSize ? 8192 |
|
|
|
, # size of the boot partition, is only used if partitionTableType is |
|
# either "efi" or "hybrid" |
|
bootSize ? 512 |
|
|
|
, # The files and directories to be placed in the target file system. |
|
# This is a list of attribute sets {source, target} where `source' |
|
# is the file system object (regular file or directory) to be |
|
# grafted in the file system at path `target'. |
|
contents ? [] |
|
|
|
, # The initial NixOS configuration file to be copied to |
|
# /etc/nixos/configuration.nix. |
|
configFile |
|
|
|
, # Shell code executed after the VM has finished. |
|
postVM ? "" |
|
|
|
, name ? "nixos-disk-image" |
|
|
|
, # Disk image format, one of qcow2, qcow2-compressed, vdi, vpc, raw. |
|
format ? "raw" |
|
|
|
, # Include a copy of Nixpkgs in the disk image |
|
includeChannel ? true |
|
, ... |
|
}: |
|
let |
|
formatOpt = if format == "qcow2-compressed" then "qcow2" else format; |
|
|
|
compress = lib.optionalString (format == "qcow2-compressed") "-c"; |
|
|
|
filename = "nixos." + { |
|
qcow2 = "qcow2"; |
|
vdi = "vdi"; |
|
vpc = "vhd"; |
|
raw = "img"; |
|
}.${formatOpt} or formatOpt; |
|
|
|
channelSources = |
|
let |
|
nixpkgs = lib.cleanSource pkgs.path; |
|
in |
|
pkgs.runCommand "nixos-${config.system.nixos.version}" {} '' |
|
mkdir -p $out |
|
cp -prd ${nixpkgs.outPath} $out/nixos |
|
chmod -R u+w $out/nixos |
|
if [ ! -e $out/nixos/nixpkgs ]; then |
|
ln -s . $out/nixos/nixpkgs |
|
fi |
|
rm -rf $out/nixos/.git |
|
echo -n ${config.system.nixos.versionSuffix} > $out/nixos/.version-suffix |
|
''; |
|
|
|
closureInfo = pkgs.closureInfo { |
|
rootPaths = [ config.system.build.toplevel ] |
|
++ (lib.optional includeChannel channelSources); |
|
}; |
|
|
|
modulesTree = pkgs.aggregateModules |
|
(with config.boot.kernelPackages; [ kernel ]); |
|
|
|
tools = lib.makeBinPath ( |
|
with pkgs; [ |
|
config.system.build.nixos-enter |
|
config.system.build.nixos-install |
|
dosfstools |
|
e2fsprogs |
|
nix |
|
parted |
|
utillinux |
|
] |
|
); |
|
|
|
stringifyProperties = prefix: properties: lib.concatStringsSep " \\\n" ( |
|
lib.mapAttrsToList |
|
( |
|
property: value: "${prefix} ${lib.escapeShellArg property}=${lib.escapeShellArg value}" |
|
) |
|
properties |
|
); |
|
|
|
image = ( |
|
pkgs.vmTools.override { |
|
rootModules = |
|
[ "9p" "9pnet_virtio" "virtio_pci" "virtio_blk" "rtc_cmos" ]; |
|
kernel = modulesTree; |
|
} |
|
).runInLinuxVM ( |
|
pkgs.runCommand name |
|
{ |
|
preVM = '' |
|
PATH=$PATH:${pkgs.qemu_kvm}/bin |
|
mkdir $out |
|
diskImage=nixos.raw |
|
qemu-img create -f raw $diskImage ${toString diskSize}M |
|
''; |
|
|
|
postVM = '' |
|
${if formatOpt == "raw" then '' |
|
mv $diskImage $out/${filename} |
|
'' else '' |
|
${pkgs.qemu}/bin/qemu-img convert -f raw -O ${formatOpt} ${compress} $diskImage $out/${filename} |
|
''} |
|
diskImage=$out/${filename} |
|
${postVM} |
|
''; |
|
} '' |
|
export PATH=${tools}:$PATH |
|
set -x |
|
|
|
cp -sv /dev/vda /dev/sda |
|
cp -sv /dev/vda /dev/xvda |
|
|
|
parted --script /dev/vda -- \ |
|
mklabel gpt \ |
|
mkpart no-fs 1MB 2MB \ |
|
align-check optimal 1 \ |
|
set 1 bios_grub on \ |
|
mkpart ESP fat32 8MB ${toString bootSize}MB \ |
|
align-check optimal 2 \ |
|
set 2 boot on \ |
|
mkpart primary ${toString bootSize}MB -1 \ |
|
align-check optimal 3 \ |
|
print |
|
|
|
mkdir /mnt |
|
mount -t tmpfs none /mnt |
|
|
|
mkdir -p /mnt/{boot,nix,etc/{nixos,ssh},var/{lib,log},srv} |
|
|
|
mkdir -p /mnt/boot |
|
mkfs.vfat /dev/vda2 -n ESP |
|
mount -t vfat /dev/vda2 /mnt/boot |
|
|
|
mkfs.ext4 -L nix /dev/vda3 |
|
mount /dev/vda3 /mnt/nix |
|
|
|
mkdir -p /mnt/nix/persist/{etc/{nixos,ssh},var/{lib,log},srv} |
|
|
|
mount -o bind /mnt/nix/persist/etc/nixos /mnt/etc/nixos |
|
mount -o bind /mnt/nix/persist/var/lib /mnt/var/lib |
|
mount -o bind /mnt/nix/persist/var/log /mnt/var/log |
|
|
|
mount |
|
|
|
# Install a configuration.nix |
|
mkdir -p /mnt/etc/nixos |
|
# `cat` so it is mutable on the fs |
|
cat ${configFile} > /mnt/etc/nixos/configuration.nix |
|
|
|
export NIX_STATE_DIR=$TMPDIR/state |
|
nix-store --load-db < ${closureInfo}/registration |
|
|
|
echo copying toplevel |
|
time nix copy --no-check-sigs --to 'local?root=/mnt/' ${config.system.build.toplevel} |
|
|
|
${lib.optionalString includeChannel '' |
|
echo copying channels |
|
time nix copy --no-check-sigs --to 'local?root=/mnt/' ${channelSources} |
|
''} |
|
|
|
echo installing bootloader |
|
time nixos-install --root /mnt --no-root-passwd \ |
|
--system ${config.system.build.toplevel} \ |
|
--substituters " " ${lib.optionalString includeChannel "--channel ${channelSources}"} |
|
|
|
df -h |
|
umount /mnt/boot |
|
'' |
|
); |
|
in |
|
image
|
|
|