Hero Image

Getting Vagrant to work with libvirt & alpine & ansible

I have had quite a time in getting vagrant to NOT work with the 23$#@$%$#%^#$$%^ virtualbox which is a horror spun from the 8th circle of hell. I use libvirt/qemu (a MUCH nicer solution!) and ansible / vagrant for setting up nice boxes. I also found a VERY NICE script for getting current alpine into a box format supported by vagrant.

  1. I Like to download this git repo to get started
  2. once there (if you aren't using debian, I just translate to os as necessary) install necessary dependencies such as vagrant, libvirt, vagrant-libvirt plugin (I will detail the crazy bits you need to get the libvirt plugin working on arch!).

I like to edit the provision.sh to include the following (Since I don't like ash, bash, or less, and I also like to add https repositories).

#!/bin/ash
set -euxo pipefail

# upgrade all packages.
apk upgrade -U --available

# setup the console keymap (keyboard layout).
# NB this is also in the answers file (but with the us keymap).
setup-keymap pt pt

# install the doas sudo shim.
apk add doas-sudo-shim

# add support for validating https certificates.
apk add ca-certificates openssl

# install the vagrant public key.
# NB vagrant will replace it on the first run.
install -d -m 700 /home/vagrant/.ssh
wget -qO /home/vagrant/.ssh/authorized_keys https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub
chmod 600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant:vagrant /home/vagrant/.ssh

# install the Guest Additions.
if [ "$(cat /sys/devices/virtual/dmi/id/board_name)" == 'VirtualBox' ]; then
# install the VirtualBox Guest Additions.
echo http://mirrors.dotsrc.org/alpine/v3.18/community >>/etc/apk/repositories
apk add -U virtualbox-guest-additions
rc-update add virtualbox-guest-additions
echo vboxsf >>/etc/modules
modinfo vboxguest
else
# install the qemu-kvm Guest Additions.
echo https://dl-cdn.alpinelinux.org/alpine/v3.18/community >>/etc/apk/repositories
echo @testing https://dl-cdn.alpinelinux.org/alpine/edge/testing >>/etc/apk/repositories
apk update
apk add -U qemu-guest-agent fish fish-tools fish-doc most@testing htop btop ncdu@testing 
rc-update add qemu-guest-agent
# configure the GA_PATH, as, for some reason, its at /dev/vport0p1 instead of
# the expected /dev/virtio-ports/org.qemu.guest_agent.0.
# NB from the host, you can test whether qemu-ga is running on the guest with:
#       virsh qemu-agent-command $(cat .vagrant/machines/default/libvirt/id) '{"execute":"guest-ping"}' | jq
#       virsh qemu-agent-command $(cat .vagrant/machines/default/libvirt/id) '{"execute":"guest-info"}' | jq
sed -i -E 's,#?(GA_PATH=).+,\1"/dev/vport0p1",' /etc/conf.d/qemu-guest-agent
fi

# install the nfs client to support nfs synced folders in vagrant.
apk add nfs-utils
apk add fish fish-doc fish-tools
# install vim.
apk add vim
apk del doas-sudo-shim
apk add sudo
# disable the DNS reverse lookup on the SSH server. this stops it from
# trying to resolve the client IP address into a DNS domain name, which
# is kinda slow and does not normally work when running inside VB.
sed -i -E 's,#?(UseDNS\s+).+,\1no,' /etc/ssh/sshd_config

# use the up/down arrows to navigate the bash history.
# NB to get these codes, press ctrl+v then the key combination you want.
cat >>/etc/inputrc <<'EOF'
"\e[A": history-search-backward
"\e[B": history-search-forward
set show-all-if-ambiguous on
set completion-ignore-case on
EOF

# setup the shell profile.
cat >/etc/profile.d/login.sh <<'EOF'
export EDITOR=vim
export PAGER=most
alias l='ls -lF --color'
alias ll='l -a'
alias h='history 25'
alias j='jobs -l'
EOF
echo "vagrant ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/vagrant
# zero the free disk space -- for better compression of the box file.
# NB prefer discard/trim (safer; faster) over creating a big zero filled file
#    (somewhat unsafe as it has to fill the entire disk, which might trigger
#    a disk (near) full alarm; slower; slightly better compression).
apk add util-linux
root_dev="$(findmnt -no SOURCE /)"
if [ "$(lsblk -no DISC-GRAN $root_dev | awk '{print $1}')" != '0B' ]; then
    while true; do
        output="$(fstrim -v /)"
        sync && sync && sync && blockdev --flushbufs $root_dev && sleep 15
        if [ "$output" == '/: 0 B (0 bytes) trimmed' ]; then
            break
        fi
    done
else
    dd if=/dev/zero of=/EMPTY bs=1M || true && sync && rm -f /EMPTY && sync
fi

Once this is done I need to add the new box to vagrant. The utility spits out the necessary command: vagrant box add -f <nameoftheboxyoumade> <nameofhteboxtobeimportedintovagrant>. Once this is done simply use the box as you would in 'normal' vagrant.

Getting libvirt installed in arch (manjaro) linux. The "missing" file

I was using arch linux and couldn't figure this out. You need the base-devel package and libvirt running, installed and working, as well as appropriate permisisons to libvirt etc. Be sure to add yourself to the libvirt group as well. NO ONE told me about that until I noticed it deep in the docs.