devbox is a simple makefile that generates disk images and libvirt domains. It
is little more than a set of carefully crafted virt-builder
and virt-install
commands. Creating a domain is as simple as running make
with a few variables
defined, either in a secondary Makefile or on the command line. But first, some
initial set up steps must be taken.
The init.sh
script need only run once. The script assumes a Fedora Workstation
host; adjust as needed. It will install the necessary packages, add libvirt NSS
modules to /etc/nsswitch.conf
, and create a storage pool for storing domain
volumes. The storage volume path is hard-coded to /var/lib/libvirt/pools/pool0
(if you change it in init.sh
, you'll need to adjust lib.mk
too). You can set
up either a filesytem storage pool or a plain directory storage pool. Set
POOL_TYPE
when running init.sh
to select the storage pool type. If you set
POOL_TYPE
to fs
, you must specify a source device path in the SOURCE_DEV
variable. For example, to use an existing device, /dev/sdc
, as a filesystem
storage pool, run: POOL_TYPE=fs SOURCE_DEV=/dev/sdc bash init.sh
. Or to use a
directory: POOL_TYPE=dir bash init.sh
. There is no default POOL_TYPE
value.
You must choose.
If your host use SELinux for access control, you will need to relabel the
directory you mount into guests with a type that can be accessed by the system
account that runs qemu
.
For example, to export $HOME/Projects
to guests, you will need to first
recursively relabel that directory:
sudo semanage fcontext --add --type svirt_home_t '/home/[^/]+/Projects(/.*)?'
sudo restorecon -Rv $HOME/Projects
Then set the CODE_DIR
make variable when installing a domain.
make -f fedora-34.mk CODE_DIR=$HOME/Projects install-fedora-34
"devbox" domains can be created by creating a .mk and .txt.in file (see
fedora-34.mk and fedora-34.txt.in as examples). The .txt.in file is use as the
value to the --commands-from-file
argument to virt-builder
. See man virt-builder
for details. The .mk file is a simple makefile that defines some
concrete targets. These targets will be fulfilled by generic targets defined in
lib.mk
.
For example, to add a centos-8 domain, create a centos-8.mk and populate with the correct values:
cat > centos-8.mk << EOF
include lib.mk
.PHONY: install
install: install-centos-8
.PHONY: uninstall
uninstall: uninstall-centos-8
# Name of the image according to virt-builder
centos-8.qcow2: OS_VERSION = centos-8.2
# Desired hostname of the guest
centos-8.qcow2 centos-8.xml install-centos-8 uninstall-centos-8: HOSTNAME = centos-8
# Name of the variant to use according to `osinfo-query os`
centos-8.xml: OS_VARIANT = centos8
EOF
And populate centos-8.txt.in with virt-builder
customization arguments:
cat > centos-8.txt.in << EOF
root-password password:fedora
install automake,autoconf,git,jq,make,sudo,vim,wget
update
run-command useradd --groups wheel --create-home --password "" @USER@; passwd --delete @USER@
ssh-inject @USER@
timezone @TIMEZONE@
append-line /etc/fstab:/code /code virtiofs defaults 0 0
selinux-relabel
EOF
Now run create and install the domain with make -f centos-8.mk install
. Once
the domain has been created, access it either by attaching directly to the
console (virsh console centos-8
) or connecting over SSH (ssh centos-8
). Once
logged in, the CODE_DIR
defined above will have been exported to the guest and
mounted to the path /code
. Any changes made to the CODE_DIR
on the host will
immediately be reflected in the guest, and vice versa.