Commit ddf53abd authored by Jörg Thalheim's avatar Jörg Thalheim
Browse files

nixos/facter: add virtualization and firmware support

This adds automatic virtualization detection (virtualisation.nix) and firmware management (firmware.nix).

Builds on PR #455151 (networking).
Part of incremental upstreaming from nixos-facter-modules.
parent e6579e37
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -6,9 +6,11 @@
{
  imports = [
    ./disk.nix
    ./firmware.nix
    ./keyboard.nix
    ./networking
    ./system.nix
    ./virtualisation.nix
  ];

  meta.maintainers = with lib.maintainers; [ mic92 ];
+24 −0
Original line number Diff line number Diff line
{ lib, config, ... }:
let
  facterLib = import ./lib.nix lib;

  inherit (config.hardware.facter) report;
  isBaremetal = config.hardware.facter.detected.virtualisation.none.enable;
  hasAmdCpu = facterLib.hasAmdCpu report;
  hasIntelCpu = facterLib.hasIntelCpu report;
in
{
  config = lib.mkIf isBaremetal {
    # none (e.g. bare-metal)
    # provide firmware for devices that might not have been detected by nixos-facter
    hardware.enableRedistributableFirmware = lib.mkDefault true;

    # update microcode
    hardware.cpu.amd.updateMicrocode = lib.mkIf hasAmdCpu (
      lib.mkDefault config.hardware.enableRedistributableFirmware
    );
    hardware.cpu.intel.updateMicrocode = lib.mkIf hasIntelCpu (
      lib.mkDefault config.hardware.enableRedistributableFirmware
    );
  };
}
+104 −0
Original line number Diff line number Diff line
{
  lib,
  config,
  options,
  ...
}:
let
  inherit (config.hardware.facter) report;
  cfg = config.hardware.facter.detected.virtualisation;
in
{
  options.hardware.facter.detected.virtualisation = {
    virtio_scsi.enable = lib.mkEnableOption "Enable the Facter Virtualisation Virtio SCSI module" // {
      default = lib.any (
        { vendor, device, ... }:
        # vendor (0x1af4) Red Hat, Inc.
        (vendor.value or 0) == 6900
        &&
          # device (0x1004, 0x1048) Virtio SCSI
          (lib.elem (device.value or 0) [
            4100
            4168
          ])
      ) (report.hardware.scsi or [ ]);
      defaultText = "hardware dependent";
    };
    oracle.enable = lib.mkEnableOption "Enable the Facter Virtualisation Oracle module" // {
      default = report.virtualisation or null == "oracle";
      defaultText = "environment dependent";
    };
    parallels.enable = lib.mkEnableOption "Enable the Facter Virtualisation Parallels module" // {
      default = report.virtualisation or null == "parallels";
      defaultText = "environment dependent";
    };
    qemu.enable = lib.mkEnableOption "Enable the Facter Virtualisation Qemu module" // {
      default = builtins.elem (report.virtualisation or null) [
        "qemu"
        "kvm"
        "bochs"
      ];
      defaultText = "environment dependent";
    };
    hyperv.enable = lib.mkEnableOption "Enable the Facter Virtualisation Hyper-V module" // {
      default = report.virtualisation or null == "microsoft";
      defaultText = "environment dependent";
    };
    # no virtualisation detected
    none.enable = lib.mkEnableOption "Enable the Facter Virtualisation None module" // {
      default = report.virtualisation or null == "none";
      defaultText = "environment dependent";
    };
  };

  config = {

    # KVM support
    boot.kernelModules =
      let
        hasCPUFeature =
          feature: lib.any ({ features, ... }: lib.elem feature features) (report.hardware.cpu or [ ]);
      in
      lib.mkMerge [
        (lib.mkIf (hasCPUFeature "vmx") [ "kvm-intel" ])
        (lib.mkIf (hasCPUFeature "svm") [ "kvm-amd" ])
      ];

    # virtio & qemu
    boot.initrd = {
      kernelModules = lib.optionals cfg.qemu.enable [
        "virtio_balloon"
        "virtio_console"
        "virtio_rng"
        "virtio_gpu"
      ];

      availableKernelModules = lib.mkMerge [
        (lib.mkIf cfg.qemu.enable [
          "virtio_net"
          "virtio_pci"
          "virtio_mmio"
          "virtio_blk"
          "9p"
          "9pnet_virtio"
        ])
        (lib.mkIf cfg.virtio_scsi.enable [
          "virtio_scsi"
        ])
      ];
    };

    virtualisation = {
      # oracle
      virtualbox.guest.enable = lib.mkIf cfg.oracle.enable (lib.mkDefault true);
      # hyper-v
      hypervGuest.enable = lib.mkIf cfg.hyperv.enable (lib.mkDefault true);
    };

    # parallels
    hardware.parallels.enable = lib.mkIf cfg.parallels.enable (lib.mkDefault true);
    nixpkgs.config = lib.mkIf (!options.nixpkgs.pkgs.isDefined && cfg.parallels.enable) {
      allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [ "prl-tools" ];
    };
  };
}