Overriding network configuration for when a virtual machine test image is built

Hi,

I’m trying to configure my NixOS servers with a flake that contains all the configurations.

I have taken a good deal of inspiration from My New Network (and deploying it with deploy-rs) - sam@samleathers.com ~ $ (although I am not using deploy-rs).

One thing I really think is cool/worthwhile is being able to build a VM to test what my server will look like before I take it to any metal. As I’m migrating from an old, non-NixOS server, this is really helping me get things prepared.

By using these commands, I can have a VM built and running quickly:

nix build .#nixosConfigurations.mymachine.config.system.build.vm
./result/bin/run-mymachine-vm

However the VM waits around for 90 seconds ‘waiting for enp3s0’, presumably because I have the following bit of configuration related to my physical server’s Ethernet port:

  networking.interfaces.enp3s0.useDHCP = false;
  networking.interfaces.enp3s0.ipv4.addresses = [
    { address = "192.168.1.2"; prefixLength = 16; }
  ];
  networking.defaultGateway = "192.168.1.254";
  networking.nameservers = [ "192.168.1.254" ];

Can I, within my NixOS config, detect that a VM image is being built and change which options I enable? Alternatively, what do other people do for this kind of situation? Have a ‘myservervm’ target which imports many of the same files in common?

Did you ever find a solution to this problem?

Solution or workaround, you decide, but

Have a ‘myservervm’ target which imports many of the same files in common?

this is what I do.

What I personally do is have a different configuration file that I import for the VM target, but equally you could probably declare some variable that you could use in e.g. mkIf

Example snippet from list of NixOS configurations:

  pea = nixosSystem {                                                    
    system = "x86_64-linux"                                              
    modules = defaultModules ++ [                                        
      ./pea/configuration_real.nix # <--- this is what I use primarily
      ./pea/configuration.nix                                            
      {                                                                  
        config._module.args = {                                          
          systemName = "pea"                                             
          isVM = false # <--- maybe this               
        }                                                                
      }                                                                  
    ]                                                                    
  }                                                                      
  peavm = nixosSystem {                                                  
    system = "x86_64-linux"                                              
    modules = defaultModules ++ [                                        
      ./pea/configuration_vm.nix # <--- notice it's a different file for the VM
      ./pea/configuration.nix                                            
      {                                                                  
        config._module.args = {                                          
          systemName = "pea"                                             
          isVM = true # <---- you could do this instead and use it within other modules (add `isVM` to the function inputs of your module, i.e. your module(s) would start with `{ config, pkgs, isVM, ... }:`
        }                                                                
      }                                                                  
    ]                                                                                     
  }