Vagrant has become the de facto tool for devops. Faster iterations, clean environments, and less overhead. This isn’t an article about why you should use Vagrant. This is an article about how to get up and running with Vagrant on Fedora with libvirt easily!
Background:
This article is an update of my original Vagrant on Fedora with libvirt article. There is still lots of good information in that article, but this one should be easier to follow and uses updated versions of Vagrant and vagrant-libvirt.
Why vagrant-libvirt?
Vagrant ships by default with support for virtualbox. This makes sense as a default since it is available on Windows, Mac, and GNU/Linux. Real hackers use GNU/Linux, and in my opinion the best tool for GNU/Linux is vagrant-libvirt. Proprietary, closed source platforms aren’t hackable and therefore aren’t cool!
Another advantage to using the vagrant-libvirt plugin is that it plays nicely with the existing ecosystem of libvirt tools. You can use virsh, virt-manager, and guestfish alongside Vagrant, and if your development work needs to go into production, you can be confident in knowing that it was already tested on the same awesome KVM virtualization platform that your servers run.
Prerequisites:
Let’s get going. What do you need?
I recommend hardware that supports VT extensions. Most does these days. This should also work with other GNU/Linux distro’s, but I haven’t tested them.
Installation:
I’m going to go through this in a logical hacking order. This means you could group all the yum install
commands into a single execution at the beginning, but you would learn much less by doing so.
First install some of your favourite hacking dependencies. I did this on a minimal, headless F20 installation. You might want to add some of these too:
# yum install -y wget tree vim screen mtr nmap telnet tar git
Update the system to make sure it’s fresh:
# yum update -y
Download Vagrant version 1.5.4. No, don’t use the latest version, it probably won’t work! Vagrant has new releases practically as often as there are sunsets, and they typically cause lots of breakages.
$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.5.4_x86_64.rpm
and install it:
# yum install -y vagrant_1.5.4_x86_64.rpm
RVM installation:
In order to get vagrant-libvirt working, you’ll need some ruby dependencies. It turns out that RVM seems to be the best way to get exactly what you need. Use the sketchy RVM installer:
# \curl -sSL https://get.rvm.io | bash -s stable
If you don’t know why that’s sketchy, then you probably shouldn’t be hacking! I did that as root, but it probably works when you run it as a normal user. At this point rvm
should be installed. The last important thing you’ll need to do is to add yourself to the rvm
group. This is only needed if you installed rvm as root:
# usermod -aG rvm <username>
You’ll probably need to logout and log back in for this to take effect. Run:
$ groups
to make sure you can see rvm in the list. If you ran rvm as root, you’ll want to source the rvm.sh
file:
$ source /etc/profile.d/rvm.sh
or simply use a new terminal. If you ran it as a normal user, I think RVM adds something to your ~/.bashrc
. You might want to reload it:
$ source ~/.bashrc
At this point RVM should be working. Let’s see which ruby’s it can install:
$ rvm list known
Ruby version ruby-2.0.0-p353
seems closest to what is available on my Fedora 20 machine, so I’ll use that:
$ rvm install ruby-2.0.0-p353
If the exact patch number isn’t available, choose what’s closest. Installing ruby requires a bunch of dependencies. The rvm install
command will ask yum for a bunch of dependencies, but if you’d rather install them yourself, you can run:
# yum install -y patch libyaml-devel libffi-devel glibc-headers autoconf gcc-c++ glibc-devel patch readline-devel zlib-devel openssl-devel bzip2 automake libtool bison
GEM installation:
Now we need the GEM dependencies for the vagrant-libvirt plugin. These GEM’s happen to have their own build dependencies, but thankfully I’ve already figured those out for you:
# yum install -y libvirt-devel libxslt-devel libxml2-devel
Now, install the nokogiri gem that vagrant-libvirt needs:
$ gem install nokogiri -v '1.5.11'
and finally we can install the actual vagrant-libvirt plugin:
$ vagrant plugin install --plugin-version 0.0.16 vagrant-libvirt
You don’t have to specify the –plugin-version 0.0.16 part, but doing so will make sure that you get a version that I have tested to be compatible with Vagrant 1.5.4 should a newer vagrant-libvirt release not be compatible with the Vagrant version you’re using. If you’re feeling brave, please test newer versions, report bugs, and write patches!
Making Vagrant more useful:
Vagrant should basically work at this point, but it’s missing some awesome. I’m proud to say that I wrote this awesome. I recommend my bash function and alias additions. If you’d like to include them, you can run:
$ wget https://gist.githubusercontent.com/purpleidea/8071962/raw/ee27c56e66aafdcb9fd9760f123e7eda51a6a51e/.bashrc_vagrant.sh $ echo '. ~/.bashrc_vagrant.sh' >> ~/.bashrc $ . ~/.bashrc # reload
to pull in my most used Vagrant aliases and functions. I’ve written about them before. If you’re interested, please read:
KVM/QEMU installation:
As I mentioned earlier, I’m assuming you have a minimal Fedora 20 installation, so you might not have all the libvirt pieces installed! Here’s how to install any potentially missing pieces:
# yum install -y libvirt{,-daemon-kvm}
This should pull in a whole bunch of dependencies too. You will need to start and (optionally) enable the libvirtd service:
# systemctl start libvirtd.service # systemctl enable libvirtd.service
You’ll notice that I’m using the systemd commands instead of the deprecated service
command. My biggest (only?) gripe with systemd is that the command line tools aren’t as friendly as they could be! The systemctl
equivalent requires more typing, and make it harder to start or stop the same service in quick succession, because it buries the action in the middle of the command instead of leaving it at the end!
The libvirtd service should finally be running. On my machine, it comes with a default network which got in the way of my vagrant-libvirt networking. If you want to get rid of it, you can run:
# virsh net-destroy default # virsh net-undefine default
and it shouldn’t bother you anymore. One last hiccup. If it’s your first time installing KVM, you might run into bz#950436. To workaround this issue, I had to run:
# rmmod kvm_intel # rmmod kvm # modprobe kvm # modprobe kvm_intel
Without this “module re-loading” you might see this error:
Call to virDomainCreateWithFlags failed: internal error: Process exited while reading console log output: char device redirected to /dev/pts/2 (label charserial0) Could not access KVM kernel module: Permission denied failed to initialize KVM: Permission denied
Additional installations:
To make your machine somewhat more palatable, you might want to consider installing bash-completion:
# yum install -y bash-completion
You’ll also probably want to add the PolicyKit (polkit) .pkla
file that I recommend in my earlier article. Typically that means adding something like:
[Allow james libvirt management permissions] Identity=unix-user:james Action=org.libvirt.unix.manage ResultAny=yes ResultInactive=yes ResultActive=yes
as root to somewhere like:
/etc/polkit-1/localauthority/50-local.d/vagrant.pkla
Your machine should now be setup perfectly! The last thing you’ll need to do is to make sure that you get a Vagrantfile that does things properly! Here are some recommendations.
Shared folders:
Shared folders are a mechanism that Vagrant uses to pass data into (and sometimes out of) the virtual machines that it is managing. Typically you can use NFS, rsync, and some provider specific folder sharing like 9p. Using rsync is the simplest to set up, and works exceptionally well. Make sure you include the following line in your Vagrantfile:
config.vm.synced_folder './', '/vagrant', type: 'rsync'
If you want to see an example of this in action, you can have a look at my puppet-gluster Vagrantfile. If you are using the puppet apply provisioner, you will have to set it to use rsync as well:
puppet.synced_folder_type = 'rsync'
KVM performance:
Due to a regression in vagrant-libvirt, the default driver used for virtual machines is qemu. If you want to use the accelerated KVM domain type, you’ll have to set it:
libvirt.driver = 'kvm'
This typically gives me a 5x performance increase over plain qemu. This fix is available in the latest vagrant-libvirt version. The default has been set to KVM in the latest git master.
Dear internets!
I think this was fairly straightforward. You could probably even put all of these commands in a shell script and just run it to get it all going. What we really need is proper RPM packaging. If you can help out, that would be excellent!
If we had a version of vagrant-libvirt alongside a matching Vagrant version in Fedora, then developers and hackers could target that, and we could easily exchange dev environments, hackers could distribute product demos as full vagrant-libvirt clusters, and I could stop having to write these types of articles 😉
I hope this was helpful to you. Please let me know in the comments.
Happy hacking,
James
2020 has not been a year we would have been able to predict. With a worldwide pandemic and lives thrown out of gear, as we head into 2021, we are thankful that our community and project continued to receive new developers, users and make small gains. For that and a...
It has been a while since we provided an update to the Gluster community. Across the world various nations, states and localities have put together sets of guidelines around shelter-in-place and quarantine. We request our community members to stay safe, to care for their loved ones, to continue to be...
The initial rounds of conversation around the planning of content for release 8 has helped the project identify one key thing – the need to stagger out features and enhancements over multiple releases. Thus, while release 8 is unlikely to be feature heavy as previous releases, it will be the...