Infinite recursion on optional import

Thanks to clever and q3k[m] on irc, I finally made it. The idea is to define instead a small module containing an option, and then the VM code will just enable that option. For example, you can create a file module_isVM.nix containing:

{ lib, pkgs, config, ... }:
with lib;                      
let
  cfg = config.custom.isVM;
in {
  # Enable it with "custom.isVM.enable = true;"
  options.custom.isVM = {
    enable = mkEnableOption "if you are inside a VM.";
  };

  # config = mkIf cfg.enable {
     # You can even put here some code specific to the VM:
  # };
}

Then you import that file in your configuration.nix:

{ config, pkgs, lib, ... }:
{
  imports =
    [
      # Defines a custom module to check if we are in a VM or not
      ./module_isVM.nix
      # Other files
      ./hardware_configuration.nix
      # ....
    ];
    # ...
}

and then you can refer to your option using config.custom.isVM.enable, for example in hardware_configuration.nix:

{ config, pkgs, lib, ... }:
# Do not use if we are in a virtual machine
lib.mkIf (!config.custom.isVM.enable) {
    boot.kernelParams = ["console=ttyS1,115200n8"];
}

Finally, you can enable this for your VM by defining in your network.nix something like:

{
  test = {pkgs, config, ...}:
    {
      imports = [ ./configuration.nix ];
      custom.isVM.enable = true;
    };
}
1 Like