Set up Vagrant with libvirt (QEMU/KVM) on NixOS

This post is a distilled version of Quickly spin up a VM containing non-NixOS but also added parts that were only mentioned implicitly or missing. It is also worth skimming through the nixos.wiki articles Virtualization in NixOS and libvirt but they look somewhat messy and it was hard to decipher which parts are relevant to which topics - but to be fair, with all these contributions I wouldn’t even know where to start so thank you so much!

These generic steps worked for me:

  1. Enable libvirt by adding the following lines to /etc/nixos/configuration.nix:

    virtualisation.libvirtd.enable = true;
    boot.kernelModules = [ "kvm-amd" "kvm-intel" ];
    
  2. Add your user to the libvirtd group (and maybe to the qemu-libvirtd as well) by modifying the users.users.<your-user>.extraGroups in /etc/nixos/configuration.nix.

    For example, this is how it looks for me:

       users.users.toraritte = {
         createHome = true;
         isNormalUser = true;
         extraGroups =
           [ "qemu-libvirtd" "libvirtd" 
             "wheel" "video" "audio" "disk" "networkmanager" 
           ]; 
         group = "users";
         home = "/home/toraritte";
         uid = 1027;
       };
    

    Note
    If you see errors similar to the ones below, then it means that your actual user is not a member of the libvirtd group.

    $ vagrant up --provider=libvirt
    Bringing machine 'default' up with 'libvirt' provider...
    Error while connecting to Libvirt: Error making a connection to libvirt URI qemu:///system?no_verify=1&keyfile=/home/toraritte/.ssh/id_rsa:
    Call to virConnectOpen failed: authentication unavailable: no polkit agent available to authenticate action 'org.libvirt.unix.manage'
    
  3. Rebuild your NixOS configuration with

    sudo nixos-rebuild switch`
    
  4. (optional) In order to not to mess up your current working dir:

    mkdir -p vagrant/vm
    cd vagrant/vm
    
  5. Add the Vagrant executable to your environment. Either with nix-env, nix-shell, in /etc/nixos/configuration.nix, etc. My preferred method is

    nix-shell -p vagrant
    
  6. Choose a libvirt-compatible Vagrant box

    Info What Vagrant boxes are to be used with vagrant init below

  7. Start the VM (chose Arch Linux for testing, but there are plenty other libvirtd-compatible Vagrant boxes)

    vagrant init generic/arch
    vagrant up --provider=libvirt
    

    Note
    Set the

    export VAGRANT_DEFAULT_PROVIDER=libvirt
    

    environment variable if you don’t want to specify the --provider on the command line every single time.

  8. Connect to the VM

    vagrant ssh
    

    Info Use vagrant status to find the ID of the VM you need, if there are multiple running. (sudo virsh list will also show some useful info.)

  9. Stop VM when finished with it

    exit
    vagrant down
    

Info
If you want to reset the VM to a blank slate, all it takes is (from inside the directory where Vagrantfile is located):

vagrant destroy
vagrant up

The grahamc/nix-install-matrix repo brings Vagrant-usage to the next level by automating provisioning a list of Vagrant boxes (i.e., Linux distros mostly), running predefined shell scripts for testing purposes, and generating a report in the end. (Some of my messy notes, still a work in progress; another caveat is that this project uses VirtualBox as the Vagrant provider, but pretty sure that one can switch to libvirt easily.)

Acknowledgements

@jacg Without your original post, this would’ve been very painful to figure out from scratch. Thanks!

@tomberek Thank you for the countless ideas and tips in this topic, and for answering my countless questions!

4 Likes