Merge pull request #180222 from YorikSar/qemu-vm-darwin-pkgs
nixos/qemu-vm: Allow to build and run VMs on Darwin
This commit is contained in:
commit
6eb620ace7
@ -4,29 +4,61 @@
|
||||
let
|
||||
zeroPad = n:
|
||||
lib.optionalString (n < 16) "0" +
|
||||
(if n > 255
|
||||
then throw "Can't have more than 255 nets or nodes!"
|
||||
else lib.toHexString n);
|
||||
(if n > 255
|
||||
then throw "Can't have more than 255 nets or nodes!"
|
||||
else lib.toHexString n);
|
||||
in
|
||||
|
||||
rec {
|
||||
qemuNicMac = net: machine: "52:54:00:12:${zeroPad net}:${zeroPad machine}";
|
||||
|
||||
qemuNICFlags = nic: net: machine:
|
||||
[ "-device virtio-net-pci,netdev=vlan${toString nic},mac=${qemuNicMac net machine}"
|
||||
[
|
||||
"-device virtio-net-pci,netdev=vlan${toString nic},mac=${qemuNicMac net machine}"
|
||||
''-netdev vde,id=vlan${toString nic},sock="$QEMU_VDE_SOCKET_${toString net}"''
|
||||
];
|
||||
|
||||
qemuSerialDevice = if pkgs.stdenv.hostPlatform.isx86 || pkgs.stdenv.hostPlatform.isRiscV then "ttyS0"
|
||||
else if (with pkgs.stdenv.hostPlatform; isAarch || isPower) then "ttyAMA0"
|
||||
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
|
||||
qemuSerialDevice =
|
||||
if pkgs.stdenv.hostPlatform.isx86 || pkgs.stdenv.hostPlatform.isRiscV then "ttyS0"
|
||||
else if (with pkgs.stdenv.hostPlatform; isAarch || isPower) then "ttyAMA0"
|
||||
else throw "Unknown QEMU serial device for system '${pkgs.stdenv.hostPlatform.system}'";
|
||||
|
||||
qemuBinary = qemuPkg: {
|
||||
x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -machine virt,accel=kvm:tcg -cpu max";
|
||||
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -machine virt,gic-version=max,accel=kvm:tcg -cpu max";
|
||||
powerpc64le-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv";
|
||||
powerpc64-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv";
|
||||
x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||
}.${pkgs.stdenv.hostPlatform.system} or "${qemuPkg}/bin/qemu-kvm";
|
||||
qemuBinary = qemuPkg:
|
||||
let
|
||||
hostStdenv = qemuPkg.stdenv;
|
||||
hostSystem = hostStdenv.system;
|
||||
guestSystem = pkgs.stdenv.hostPlatform.system;
|
||||
|
||||
linuxHostGuestMatrix = {
|
||||
x86_64-linux = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||
armv7l-linux = "${qemuPkg}/bin/qemu-system-arm -machine virt,accel=kvm:tcg -cpu max";
|
||||
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -machine virt,gic-version=max,accel=kvm:tcg -cpu max";
|
||||
powerpc64le-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv";
|
||||
powerpc64-linux = "${qemuPkg}/bin/qemu-system-ppc64 -machine powernv";
|
||||
x86_64-darwin = "${qemuPkg}/bin/qemu-kvm -cpu max";
|
||||
};
|
||||
otherHostGuestMatrix = {
|
||||
aarch64-darwin = {
|
||||
aarch64-linux = "${qemuPkg}/bin/qemu-system-aarch64 -machine virt,gic-version=2,accel=hvf:tcg -cpu max";
|
||||
};
|
||||
x86_64-darwin = {
|
||||
x86_64-linux = "${qemuPkg}/bin/qemu-system-x86_64 -machine type=q35,accel=hvf:tcg -cpu max";
|
||||
};
|
||||
};
|
||||
|
||||
throwUnsupportedHostSystem =
|
||||
let
|
||||
supportedSystems = [ "linux" ] ++ (lib.attrNames otherHostGuestMatrix);
|
||||
in
|
||||
throw "Unsupported host system ${hostSystem}, supported: ${lib.concatStringsSep ", " supportedSystems}";
|
||||
throwUnsupportedGuestSystem = guestMap:
|
||||
throw "Unsupported guest system ${guestSystem} for host ${hostSystem}, supported: ${lib.concatStringsSep ", " (lib.attrNames guestMap)}";
|
||||
in
|
||||
if hostStdenv.isLinux then
|
||||
linuxHostGuestMatrix.${guestSystem} or "${qemuPkg}/bin/qemu-kvm"
|
||||
else
|
||||
let
|
||||
guestMap = (otherHostGuestMatrix.${hostSystem} or throwUnsupportedHostSystem);
|
||||
in
|
||||
(guestMap.${guestSystem} or (throwUnsupportedGuestSystem guestMap));
|
||||
}
|
||||
|
@ -102,7 +102,9 @@ let
|
||||
# Shell script to start the VM.
|
||||
startVM =
|
||||
''
|
||||
#! ${pkgs.runtimeShell}
|
||||
#! ${cfg.host.pkgs.runtimeShell}
|
||||
|
||||
export PATH=${makeBinPath [ cfg.host.pkgs.coreutils ]}''${PATH:+:}$PATH
|
||||
|
||||
set -e
|
||||
|
||||
@ -574,11 +576,24 @@ in
|
||||
description = "Primary IP address used in /etc/hosts.";
|
||||
};
|
||||
|
||||
virtualisation.host.pkgs = mkOption {
|
||||
type = options.nixpkgs.pkgs.type;
|
||||
default = pkgs;
|
||||
defaultText = "pkgs";
|
||||
example = literalExpression ''
|
||||
import pkgs.path { system = "x86_64-darwin"; }
|
||||
'';
|
||||
description = ''
|
||||
pkgs set to use for the host-specific packages of the vm runner.
|
||||
Changing this to e.g. a Darwin package set allows running NixOS VMs on Darwin.
|
||||
'';
|
||||
};
|
||||
|
||||
virtualisation.qemu = {
|
||||
package =
|
||||
mkOption {
|
||||
type = types.package;
|
||||
default = pkgs.qemu_kvm;
|
||||
default = cfg.host.pkgs.qemu_kvm;
|
||||
example = "pkgs.qemu_test";
|
||||
description = lib.mdDoc "QEMU package to use.";
|
||||
};
|
||||
@ -1075,14 +1090,14 @@ in
|
||||
|
||||
services.qemuGuest.enable = cfg.qemu.guestAgent.enable;
|
||||
|
||||
system.build.vm = pkgs.runCommand "nixos-vm" {
|
||||
system.build.vm = cfg.host.pkgs.runCommand "nixos-vm" {
|
||||
preferLocalBuild = true;
|
||||
meta.mainProgram = "run-${config.system.name}-vm";
|
||||
}
|
||||
''
|
||||
mkdir -p $out/bin
|
||||
ln -s ${config.system.build.toplevel} $out/system
|
||||
ln -s ${pkgs.writeScript "run-nixos-vm" startVM} $out/bin/run-${config.system.name}-vm
|
||||
ln -s ${cfg.host.pkgs.writeScript "run-nixos-vm" startVM} $out/bin/run-${config.system.name}-vm
|
||||
'';
|
||||
|
||||
# When building a regular system configuration, override whatever
|
||||
|
Loading…
Reference in New Issue
Block a user