As a user of CoreOS/Container Linux for many years, and I’ve been eagerly awaiting Fedora CoreOS. I’ve even replaced my Desktop with Silverblue just to get a feel for things to come. For Container Linux I’ve made some advanced (read: complex) Vagrant projects to develop and test our deployment setups locally. Now that some build artifacts have shown up, I thought it was a good time to experiment and try to get them up and running in Vagrant on Silverblue.
Vagrant on Silverblue
Overlay libvirt
Libvirt needs to be installed on the host directly, so you need to overlay at least the ‘libvirt’ package.
rpm-ostree install virt-install virt-manager
systemctl reboot
To get rid of password prompts for each and every libvirt action, install the following polkit rule:
sudo tee /etc/polkit-1/rules.d/80-libvirt.rules <<EOF
polkit.addRule(function(action, subject) {
if (action.id == "org.libvirt.unix.manage" && subject.local && subject.active && subject.isInGroup("wheel")) {
return polkit.Result.YES;
}
});
EOF
Note this requires you are in the wheel group, if you have an admin account on Silveblue that will be the case.
Libvirt should now be up and running:
$ LIBVIRT_DEFAULT_URI=qemu:///system virsh list
# Id Name State
# ------------------------------
Vagrant in a Container
Vagrant can run fine from a container. Create a container image with:
cat - > Dockerfile <<EOF
FROM docker://registry.fedoraproject.org/fedora:30
RUN dnf install -y openssh-clients vagrant vagrant-libvirt
CMD [ "/bin/bash" ]
EOF
podman build -t localhost/vagrant-container:latest .
This Vagrant container can be started interactivly with:
podman run --rm -it \
--volume /run/libvirt:/run/libvirt \
--volume "${HOME}:${HOME}:rslave" \
--env "HOME=${HOME}" \
--workdir "$(pwd)" \
--net host \
--privileged \
--security-opt label=disable \
localhost/vagrant-container:latest
By added the following alias to your ~/.bashrc
, the vagrant commands can be executed transparantly using this container:
alias vagrant='podman run --rm -it \
--volume /run/libvirt:/run/libvirt \
--volume "${HOME}:${HOME}:rslave" \
--env "HOME=${HOME}" \
--workdir "$(pwd)" \
--net host \
--privileged \
--security-opt label=disable \
--entrypoint /usr/bin/vagrant \
localhost/vagrant-container:latest'
Building a Fedora CoreOS Vagrant Box
To package up the latest qcow2 image artifact from the ci server, I made a little makefile/container and put it on github. Use the following commands to clone the repo and build the container image with the Makefile and it’s dependencies:
git clone https://github.com/basvdlei/fedora-coreos-vagrant-box-builder.git
cd fedora-coreos-vagrant-box-builder
podman build -t localhost/box-builder:latest .
When this container is started, it will download the latest qcow2 image and package it up as box into the /output
volume:
mkdir output
podman run --rm -v "$(pwd)/output:/output:Z" localhost/box-builder:latest
It creates two files (fedora-coreos.box
and fedora-coreos.json
) in the output directory. Import them in Vagrant with:
cd output
vagrant box add fedora-coreos.json
To show the installed boxes:
vagrant box list
# fedora-coreos-preview (libvirt, 30.83)
Simple Vagrant Fedora CoreOS Project
Now that we have Libvirt, Vagrant and a Fedora CoreOS box, it’s finally time to start and boot a sample Fedora CoreOS project.
Create a project directory and put the following contents in file called Vagrant
require 'json'
ignition_file = File.join(File.dirname(__FILE__), 'config.ign')
config = {
:ignition => {
:version => "3.0.0",
},
:passwd => {
:users => [{
:name => 'core',
:sshAuthorizedKeys => ['ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key'],
}],
},
}
File.open(ignition_file, "w") { |file| file.puts JSON.generate(config)}
# Systems with SELinux will need to relabel the file.
system("chcon system_u:object_r:virt_content_t:s0 #{ignition_file}")
Vagrant.configure("2") do |config|
config.vm.box = 'fedora-coreos-preview'
config.vm.provider :libvirt do |lv|
lv.memory = 1024
lv.cpus = 1
lv.qemuargs :value => '-fw_cfg'
lv.qemuargs :value => "name=opt/com.coreos/config,file=#{ignition_file}"
end
end
When you run vagrant status
(or any other vagrant command) it should create an config.ign
file. This is the Ignition config the VM will be booted with. The example above only installs the default Vagrant insecure SSH key. Full Ignition specs can be found here.
To start up the VM type:
vagrant up
When it’s finished creating and booting the machine, you can login to it with:
vagrant ssh
If everything went as it should, you should get a login prompt:
Fedora 30.83 (CoreOS preview)
Tracker: https://github.com/coreos/fedora-coreos-tracker
WARNING: All aspects subject to change, highly experimental
[core@localhost ~]$
Cheers!
As a side-note, I did play around with cosa, which is awesome. But I really wanted to migrate my current Vagrant projects over.