mirror of
https://github.com/SebastianWendel/nixpkgs.git
synced 2024-09-21 04:49:01 +02:00
Merge pull request #55645 from eonpatapon/qemu-vm-drives
nixos/qemu-vm: declarative drives
This commit is contained in:
commit
59e731b0ac
|
@ -23,24 +23,56 @@ let
|
||||||
|
|
||||||
cfg = config.virtualisation;
|
cfg = config.virtualisation;
|
||||||
|
|
||||||
qemuGraphics = lib.optionalString (!cfg.graphics) "-nographic";
|
|
||||||
|
|
||||||
consoles = lib.concatMapStringsSep " " (c: "console=${c}") cfg.qemu.consoles;
|
consoles = lib.concatMapStringsSep " " (c: "console=${c}") cfg.qemu.consoles;
|
||||||
|
|
||||||
# XXX: This is very ugly and in the future we really should use attribute
|
driveOpts = { ... }: {
|
||||||
# sets to build ALL of the QEMU flags instead of this mixed mess of Nix
|
|
||||||
# expressions and shell script stuff.
|
options = {
|
||||||
mkDiskIfaceDriveFlag = idx: driveArgs: let
|
|
||||||
inherit (cfg.qemu) diskInterface;
|
file = mkOption {
|
||||||
# The drive identifier created by incrementing the index by one using the
|
type = types.str;
|
||||||
# shell.
|
description = "The file image used for this drive.";
|
||||||
drvId = "drive$((${idx} + 1))";
|
};
|
||||||
# NOTE: DO NOT shell escape, because this may contain shell variables.
|
|
||||||
commonArgs = "index=${idx},id=${drvId},${driveArgs}";
|
driveExtraOpts = mkOption {
|
||||||
isSCSI = diskInterface == "scsi";
|
type = types.attrsOf types.str;
|
||||||
devArgs = "${diskInterface}-hd,drive=${drvId}";
|
default = {};
|
||||||
args = "-drive ${commonArgs},if=none -device lsi53c895a -device ${devArgs}";
|
description = "Extra options passed to drive flag.";
|
||||||
in if isSCSI then args else "-drive ${commonArgs},if=${diskInterface}";
|
};
|
||||||
|
|
||||||
|
deviceExtraOpts = mkOption {
|
||||||
|
type = types.attrsOf types.str;
|
||||||
|
default = {};
|
||||||
|
description = "Extra options passed to device flag.";
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
driveCmdline = idx: { file, driveExtraOpts, deviceExtraOpts, ... }:
|
||||||
|
let
|
||||||
|
drvId = "drive${toString idx}";
|
||||||
|
mkKeyValue = generators.mkKeyValueDefault {} "=";
|
||||||
|
mkOpts = opts: concatStringsSep "," (mapAttrsToList mkKeyValue opts);
|
||||||
|
driveOpts = mkOpts (driveExtraOpts // {
|
||||||
|
index = idx;
|
||||||
|
id = drvId;
|
||||||
|
"if" = "none";
|
||||||
|
inherit file;
|
||||||
|
});
|
||||||
|
deviceOpts = mkOpts (deviceExtraOpts // {
|
||||||
|
drive = drvId;
|
||||||
|
});
|
||||||
|
device =
|
||||||
|
if cfg.qemu.diskInterface == "scsi" then
|
||||||
|
"-device lsi53c895a -device scsi-hd,${deviceOpts}"
|
||||||
|
else
|
||||||
|
"-device virtio-blk-pci,${deviceOpts}";
|
||||||
|
in
|
||||||
|
"-drive ${driveOpts} ${device}";
|
||||||
|
|
||||||
|
drivesCmdLine = drives: concatStringsSep " " (imap1 driveCmdline drives);
|
||||||
|
|
||||||
# Shell script to start the VM.
|
# Shell script to start the VM.
|
||||||
startVM =
|
startVM =
|
||||||
|
@ -77,13 +109,11 @@ let
|
||||||
''}
|
''}
|
||||||
|
|
||||||
cd $TMPDIR
|
cd $TMPDIR
|
||||||
idx=2
|
idx=0
|
||||||
extraDisks=""
|
|
||||||
${flip concatMapStrings cfg.emptyDiskImages (size: ''
|
${flip concatMapStrings cfg.emptyDiskImages (size: ''
|
||||||
if ! test -e "empty$idx.qcow2"; then
|
if ! test -e "empty$idx.qcow2"; then
|
||||||
${qemu}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M"
|
${qemu}/bin/qemu-img create -f qcow2 "empty$idx.qcow2" "${toString size}M"
|
||||||
fi
|
fi
|
||||||
extraDisks="$extraDisks ${mkDiskIfaceDriveFlag "$idx" "file=$(pwd)/empty$idx.qcow2,werror=report"}"
|
|
||||||
idx=$((idx + 1))
|
idx=$((idx + 1))
|
||||||
'')}
|
'')}
|
||||||
|
|
||||||
|
@ -97,21 +127,7 @@ let
|
||||||
-virtfs local,path=/nix/store,security_model=none,mount_tag=store \
|
-virtfs local,path=/nix/store,security_model=none,mount_tag=store \
|
||||||
-virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \
|
-virtfs local,path=$TMPDIR/xchg,security_model=none,mount_tag=xchg \
|
||||||
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
|
-virtfs local,path=''${SHARED_DIR:-$TMPDIR/xchg},security_model=none,mount_tag=shared \
|
||||||
${if cfg.useBootLoader then ''
|
${drivesCmdLine config.virtualisation.qemu.drives} \
|
||||||
${mkDiskIfaceDriveFlag "0" "file=$NIX_DISK_IMAGE,cache=writeback,werror=report"} \
|
|
||||||
${mkDiskIfaceDriveFlag "1" "file=$TMPDIR/disk.img,media=disk"} \
|
|
||||||
${if cfg.useEFIBoot then ''
|
|
||||||
-pflash $TMPDIR/bios.bin \
|
|
||||||
'' else ''
|
|
||||||
''}
|
|
||||||
'' else ''
|
|
||||||
${mkDiskIfaceDriveFlag "0" "file=$NIX_DISK_IMAGE,cache=writeback,werror=report"} \
|
|
||||||
-kernel ${config.system.build.toplevel}/kernel \
|
|
||||||
-initrd ${config.system.build.toplevel}/initrd \
|
|
||||||
-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS" \
|
|
||||||
''} \
|
|
||||||
$extraDisks \
|
|
||||||
${qemuGraphics} \
|
|
||||||
${toString config.virtualisation.qemu.options} \
|
${toString config.virtualisation.qemu.options} \
|
||||||
$QEMU_OPTS \
|
$QEMU_OPTS \
|
||||||
"$@"
|
"$@"
|
||||||
|
@ -367,6 +383,12 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
drives =
|
||||||
|
mkOption {
|
||||||
|
type = types.listOf (types.submodule driveOpts);
|
||||||
|
description = "Drives passed to qemu.";
|
||||||
|
};
|
||||||
|
|
||||||
diskInterface =
|
diskInterface =
|
||||||
mkOption {
|
mkOption {
|
||||||
default = "virtio";
|
default = "virtio";
|
||||||
|
@ -476,8 +498,49 @@ in
|
||||||
|
|
||||||
# FIXME: Consolidate this one day.
|
# FIXME: Consolidate this one day.
|
||||||
virtualisation.qemu.options = mkMerge [
|
virtualisation.qemu.options = mkMerge [
|
||||||
(mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [ "-vga std" "-usb" "-device usb-tablet,bus=usb-bus.0" ])
|
(mkIf (pkgs.stdenv.isi686 || pkgs.stdenv.isx86_64) [
|
||||||
(mkIf (pkgs.stdenv.isAarch32 || pkgs.stdenv.isAarch64) [ "-device virtio-gpu-pci" "-device usb-ehci,id=usb0" "-device usb-kbd" "-device usb-tablet" ])
|
"-vga std" "-usb" "-device usb-tablet,bus=usb-bus.0"
|
||||||
|
])
|
||||||
|
(mkIf (pkgs.stdenv.isAarch32 || pkgs.stdenv.isAarch64) [
|
||||||
|
"-device virtio-gpu-pci" "-device usb-ehci,id=usb0" "-device usb-kbd" "-device usb-tablet"
|
||||||
|
])
|
||||||
|
(mkIf (!cfg.useBootLoader) [
|
||||||
|
"-kernel ${config.system.build.toplevel}/kernel"
|
||||||
|
"-initrd ${config.system.build.toplevel}/initrd"
|
||||||
|
''-append "$(cat ${config.system.build.toplevel}/kernel-params) init=${config.system.build.toplevel}/init regInfo=${regInfo}/registration ${consoles} $QEMU_KERNEL_PARAMS"''
|
||||||
|
])
|
||||||
|
(mkIf cfg.useEFIBoot [
|
||||||
|
"-pflash $TMPDIR/bios.bin"
|
||||||
|
])
|
||||||
|
(mkIf (!cfg.graphics) [
|
||||||
|
"-nographic"
|
||||||
|
])
|
||||||
|
];
|
||||||
|
|
||||||
|
virtualisation.qemu.drives = mkMerge [
|
||||||
|
(mkIf cfg.useBootLoader [
|
||||||
|
{
|
||||||
|
file = "$NIX_DISK_IMAGE";
|
||||||
|
driveExtraOpts.cache = "writeback";
|
||||||
|
driveExtraOpts.werror = "report";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
file = "$TMPDIR/disk.img";
|
||||||
|
driveExtraOpts.media = "disk";
|
||||||
|
deviceExtraOpts.bootindex = "1";
|
||||||
|
}
|
||||||
|
])
|
||||||
|
(mkIf (!cfg.useBootLoader) [
|
||||||
|
{
|
||||||
|
file = "$NIX_DISK_IMAGE";
|
||||||
|
driveExtraOpts.cache = "writeback";
|
||||||
|
driveExtraOpts.werror = "report";
|
||||||
|
}
|
||||||
|
])
|
||||||
|
(imap0 (idx: _: {
|
||||||
|
file = "$(pwd)/empty${toString idx}.qcow2";
|
||||||
|
driveExtraOpts.werror = "report";
|
||||||
|
}) cfg.emptyDiskImages)
|
||||||
];
|
];
|
||||||
|
|
||||||
# Mount the host filesystem via 9P, and bind-mount the Nix store
|
# Mount the host filesystem via 9P, and bind-mount the Nix store
|
||||||
|
|
Loading…
Reference in a new issue