Merge pull request #92205 from chkno/qemu-vm-cleanup

qemu-vm device name cleanup
This commit is contained in:
Niklas Hambüchen 2020-07-04 15:08:52 +02:00 committed by GitHub
commit 7c903ca1d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -46,6 +46,13 @@ let
description = "Extra options passed to device flag."; description = "Extra options passed to device flag.";
}; };
name = mkOption {
type = types.nullOr types.str;
default = null;
description =
"A name for the drive. Must be unique in the drives list. Not passed to qemu.";
};
}; };
}; };
@ -74,6 +81,24 @@ let
drivesCmdLine = drives: concatStringsSep " " (imap1 driveCmdline drives); drivesCmdLine = drives: concatStringsSep " " (imap1 driveCmdline drives);
# Creates a device name from a 1-based a numerical index, e.g.
# * `driveDeviceName 1` -> `/dev/vda`
# * `driveDeviceName 2` -> `/dev/vdb`
driveDeviceName = idx:
let letter = elemAt lowerChars (idx - 1);
in if cfg.qemu.diskInterface == "scsi" then
"/dev/sd${letter}"
else
"/dev/vd${letter}";
lookupDriveDeviceName = driveName: driveList:
(findSingle (drive: drive.name == driveName)
(throw "Drive ${driveName} not found")
(throw "Multiple drives named ${driveName}") driveList).device;
addDeviceNames =
imap1 (idx: drive: drive // { device = driveDeviceName idx; });
# Shell script to start the VM. # Shell script to start the VM.
startVM = startVM =
'' ''
@ -396,6 +421,7 @@ in
mkOption { mkOption {
type = types.listOf (types.submodule driveOpts); type = types.listOf (types.submodule driveOpts);
description = "Drives passed to qemu."; description = "Drives passed to qemu.";
apply = addDeviceNames;
}; };
diskInterface = diskInterface =
@ -512,8 +538,7 @@ in
optional cfg.writableStore "overlay" optional cfg.writableStore "overlay"
++ optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx"; ++ optional (cfg.qemu.diskInterface == "scsi") "sym53c8xx";
virtualisation.bootDevice = virtualisation.bootDevice = mkDefault (driveDeviceName 1);
mkDefault (if cfg.qemu.diskInterface == "scsi" then "/dev/sda" else "/dev/vda");
virtualisation.pathsInNixDB = [ config.system.build.toplevel ]; virtualisation.pathsInNixDB = [ config.system.build.toplevel ];
@ -542,25 +567,20 @@ in
]; ];
virtualisation.qemu.drives = mkMerge [ virtualisation.qemu.drives = mkMerge [
(mkIf cfg.useBootLoader [ [{
{ name = "root";
file = "$NIX_DISK_IMAGE"; file = "$NIX_DISK_IMAGE";
driveExtraOpts.cache = "writeback"; driveExtraOpts.cache = "writeback";
driveExtraOpts.werror = "report"; driveExtraOpts.werror = "report";
} }]
(mkIf cfg.useBootLoader [
{ {
name = "boot";
file = "$TMPDIR/disk.img"; file = "$TMPDIR/disk.img";
driveExtraOpts.media = "disk"; driveExtraOpts.media = "disk";
deviceExtraOpts.bootindex = "1"; deviceExtraOpts.bootindex = "1";
} }
]) ])
(mkIf (!cfg.useBootLoader) [
{
file = "$NIX_DISK_IMAGE";
driveExtraOpts.cache = "writeback";
driveExtraOpts.werror = "report";
}
])
(imap0 (idx: _: { (imap0 (idx: _: {
file = "$(pwd)/empty${toString idx}.qcow2"; file = "$(pwd)/empty${toString idx}.qcow2";
driveExtraOpts.werror = "report"; driveExtraOpts.werror = "report";
@ -608,7 +628,7 @@ in
}; };
} // optionalAttrs cfg.useBootLoader } // optionalAttrs cfg.useBootLoader
{ "/boot" = { "/boot" =
{ device = "/dev/vdb2"; { device = "${lookupDriveDeviceName "boot" cfg.qemu.drives}2";
fsType = "vfat"; fsType = "vfat";
options = [ "ro" ]; options = [ "ro" ];
noCheck = true; # fsck fails on a r/o filesystem noCheck = true; # fsck fails on a r/o filesystem