A Test Kitchen Driver for QEMU.
Test Kitchen and QEMU should be installed. To use KVM acceleration
you should have read/write access to
/dev/kvm. This is usually
done by adding your user to the
This driver is installable via
gem install kitchen-qemu.
Please read the Kitchen docs for more details
on how to configure Kitchen to use this driver.
Images for use with kitchen-qemu can be downloaded from
These are all generated by this cookbook.
Create a bootable image of your favourite *NIX and go through the following checklist:
Create a user for kitchen to use. This can be root but should preferably be a different user. The username
kitchenare good choices.
Install sudo and make sure the
kitchenuser has password-less sudo rights. Eg.
# echo 'kitchen ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/kitchen
By default each instance gets a single network interface. Make sure the image uses DHCP to automatically configure an IPv4 address on this interface. Usually its
ens3, but can be named something else.
Install an SSH server and make sure it is started automatically at boot and listens on port 22.
Install curl, wget or something similar for downloading Chef from the guest or pre-install the Chef Omnibus package for even faster converge times.
Bonus points for automatically starting a getty on the first serial port. This way you can log into the guest without using SSH like so:
$ socat -,cfmakeraw,escape=0xf .kitchen/<instance name>.mon
Use Ctrl-o to exit socat.
Berkshelf has a bug
(they wont fix)
that makes it crash if it encounters a named unix socket
when uploading cookbooks to the guest.
This will happen when uploading the cookbook in the current
directory since that includes the
.kitchen directory where
kitchen-qemu creates two unix sockets for each running instance.
One is a "serial terminal" and one is used to shutdown the running
To work around this bug make Berkshelf ignore the
directory by adding it to a
chefignore file. Eg.
$ echo .kitchen >> chefignore
Alternatively create a
Cheffile and let kitchen use
to resolve cookbook dependencies.
This setting is required to specify the path to a bootable disk image. It'll only be opened for reading. Any changes shall be written to temporary storage and lost once the instance is destroyed. Eg.:
driver: name: qemu platforms: - name: myplatform driver: image: /path/to/mybootable.qcow2
See above for how to prepare images for use with kitchen-qemu.
For advanced uses this setting can also be a list of maps describing several images to attach to the guest. Eg.:
driver: name: qemu platforms: - name: myplatform driver: image: # opened read-only, guest changes discarded when shut down - file: /path/to/bootable.qcow2 # opened read/write, guest changes persisted - file: /path/to/writable.qcow2 snapshot: off # opened read-only, guest cannot write to it - file: /path/to/readonly.qcow2 readonly: on
Specifies the default path for images. That is unless the absolute path to the an image file is given this path is prepended.
Defaults to the following:
- if the
KITCHEN_QEMU_IMAGESenvironment variable if set use that
XDG_CONFIG_HOMEis set use
HOMEis set use
- fall back to
This means the following
.kitchen.yml will usually look for
driver: name: qemu platforms: - name: jessie driver: image: jessie.qcow2 - name: trusty driver: image: trusty.qcow2
Determines the QEMU command to run:
Explicitly set which QEMU binary to run.
Defaults to unset which means the binary is guessed from the
Username to use when SSH'ing to the instance.
Password to use when first SSH'ing to the instance. This is only used when creating the instance. Subsequent connections will use a built-in RSA key-pair.
Determines which port QEMU will listen on. Connections to localhost on this port are forwarded to port 22 on the guest which should accept incoming SSH connections there.
Defaults to unset which means a random free port is used.
Determines the lowest port number to pick when the port is not specified.
Defaults to 1025.
Determines the highest port number to pick when the port is not specified.
Defaults to 65535.
Determines whether to enable KVM acceleration or not.
Defaults to unset which means kitchen-qemu will check
/dev/kvm is both readable and writable before
Sets the -display option for QEMU. Set to
to get a virtual screen window. This may be helpful to
debug why your image doesn't respond to SSH.
Defaults to `none' which means no window is displayed.
Use bios implementation at the given path.
Sets the number of virtual CPUs to give the instance. Alternatively set one or more of the following 3 options for more control over the virtual CPU topology.
Defaults to 1.
Sets the number of CPU sockets in each instance.
Defaults to 1.
Sets the number of cores in each instance CPU.
Defaults to 1.
Sets the number of threads in each instance CPU core.
Defaults to 1.
Determines the number of megabytes of RAM to give the instance.
Defaults to 512 (MiB).
Specify NICs and networks. If not specified it defaults to
suites: - name: mysuite driver: networks: - netdev: user,id=user,net=192.168.1.0/24,hostname=%h,hostfwd=tcp::%p-:22 device: virtio-net-pci,netdev=user
If a netdev entry contains a
hostname=%h setting the
%h is replaced by the
configured hostname of the guest. Similarly when setting
replaced by the possibly random port chosen for kitchen to connect to.
See the port option above.
Set the hostname of the guest.
Defaults to the instance name.
Share parts of the host filesystem with the guest. Eg.
suites: - name: mysuite driver: hostshares: - path: my/shared/directory # path to export mountpoint: /mnt # mountpoint inside the guest
If the path is not an absolute path it is taken relative to the
directory of the
.kitchen.yml. The shared path is automatically mounted
at the specified mountpoint inside the guest.
This is similar to Vagrant's synced_folders, but uses QEMU's builtin
9pfs over virtio feature. On Linux this requires the 9p and 9pnet_virtio
modules to be loadable or built in.
Determines how guests are closed when running
true an ACPI poweroff event is sent to the guest which
is expected to respond by closing down gracefully. This is
like pressing a virtual power button on the virtual machine.
false QEMU is simply shut down immediately. This is faster
but similar to forcefully pulling the power from the virtual machine.
false when all attached disk images are snapshotted or
Determines whether or not a Chef Omnibus package will be installed. There are several different behaviors available:
true- the latest release will be installed. Subsequent converges will skip re-installing if chef is present.
latest- the latest release will be installed. Subsequent converges will always re-install even if chef is present.
10.24.0) - the desired version string will be passed the the install.sh script. Subsequent converges will skip if the installed version and the desired version match.
nil- no chef is installed.
The default value is unset, or
Adds arbitrary command line arguments to the QEMU command line. Example use:
platforms: - name: jessie driver: image: jessie.qcow2 args: - chardev: socket,id=ipmi0,host=localhost,port=9002,reconnect=10 - device: ipmi-bmc-extern,id=bmc0,chardev=ipmi0 - device: isa-ipmi-bt,bmc=bmc0
Note: There is no code in kitchen-qemu which ensures that there’s no
args options and options automatically generated by
args to add more devices needed for a test should be
fine though. The arguments are appended to the end of the QEMU command line,
behind all other options.
Pull requests are very welcome! Make sure your patches are well tested. Ideally create a topic branch for every separate change you make. For example:
- Fork the repo
- Create your feature branch (
git checkout -b my-new-feature)
- Commit your changes (
git commit -am 'Added some feature')
- Push to the branch (
git push origin my-new-feature)
- Create new Pull Request
GPLv3 or later (see LICENSE)