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, without all these contributions I wouldn’t even know where to start so thank you so much!
These generic steps worked for me:
-
Enable
libvirt
by adding the following lines to/etc/nixos/configuration.nix
:virtualisation.libvirtd.enable = true; boot.kernelModules = [ "kvm-amd" "kvm-intel" ];
-
Add your user to the
libvirtd
group (and maybe to theqemu-libvirtd
as well) by modifying theusers.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 thelibvirtd
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'
-
Rebuild your NixOS configuration with
sudo nixos-rebuild switch
-
(optional) In order to not to mess up your current working dir:
mkdir -p vagrant/vm cd vagrant/vm
-
Add the Vagrant executable to your environment. Either with
nix-env
,nix-shell
, in/etc/nixos/configuration.nix
, etc. My preferred method isnix-shell -p vagrant
-
Choose a
libvirt
-compatible Vagrant boxInfo What Vagrant boxes are to be used with
vagrant init
below -
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 theexport VAGRANT_DEFAULT_PROVIDER=libvirt
environment variable if you don’t want to specify the
--provider
on the command line every single time. -
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.) -
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 whereVagrantfile
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!