This is a Vagrant plugin that adds a simple QEMU provider to Vagrant, allowing Vagrant to control and provision machines using QEMU.
Notes: test with Apple Silicon / M1 and CentOS / Ubuntu aarch64 image
Tested:
Others:
config.vm.provider "qemu" do |qe|
qe.machine = "virt,accel=hvf,highmem=off"
qe.cpu = "cortex-a72"
end
Make sure QEMU is installed, if not:
brew install qemu
Install plugin:
vagrant plugin install vagrant-qemu
Prepare a Vagrantfile
, see Example, and start:
vagrant up --provider qemu
Notes:
Same as vagrant-libvirt version-1:
box.img
metadata.json
file describing box image (provider, virtual_size, format)Vagrantfile
that does default settingsThis provider exposes a few provider-specific configuration options:
ssh_port
- The SSH port number used to access VM, default: 50022
arch
- The architecture of VM, default: aarch64
machine
- The machine type of VM, default: virt,accel=hvf,highmem=off
cpu
- The cpu model of VM, default: cortex-a72
smp
- The smp setting (Simulate an SMP system with n CPUs) of VM, default: 2
memory
- The memory setting of VM, default: 4G
ssh_host
- The SSH IP used to access VM, default: 127.0.0.1
net_device
- The network device, default: virtio-net-device
drive_interface
- The interface type for the main drive, default virtio
image_path
- The path (or array of paths) to qcow2 image for box-less VM, default is nil valueqemu_dir
- The path to QEMU's install dir, default: /opt/homebrew/share/qemu
extra_qemu_args
- The raw list of additional arguments to pass to QEMU. Use with extreme caution. (see "Force Multicore" below as example)extra_netdev_args
- extra, comma-separated arguments to pass to the -netdev parameter. Use with caution. (see "Force Local IP" below as example)control_port
- The port number used to control vm from vagrant, default is nil value. (nil means use unix socket)debug_port
- The port number used to export serial port of the vm for debug, default is nil value. (nil means use unix socket, see "Debug" below for details)no_daemonize
- Disable the "daemonize" mode of QEMU, default is false. (see "Windows host" below as example)firmware_format
- The format of aarch64 firmware images (edk2-aarch64-code.fd
and edk2-arm-vars.fd
) loaded from qemu_dir
, default: raw
other_default
- The other default arguments used by this plugin, default: %W(-parallel null -monitor none -display none -vga none)
These can be set like typical provider-specific configuration:
# Basic Vagrant config (API version 2)
Vagrant.configure(2) do |config|
# ... other stuff
config.vm.provider "qemu" do |qe|
qe.memory = "8G"
end
end
nil
valueTo be able to custom the result qemu command deeply, you can set some config options
to nil
value to skip related qemu arguments.
machine
: skip -machine xxx
cpu
: skip -cpu xxx
smp
: skip -smp xxx
memory
: skip -m xxx
net_device
: skip all network related arguments:
-device xxx,netdev=net0
-netdev user,id=net0,xxx
drive_interface
: skip drive for the main image, -drive if=xxx,xxx
firmware_format
: skip firmware setup for aarch64, -drive if=pflash,xxx
With other_default = []
, all default arguments will be skipped.
vagrant init ppggff/centos-7-aarch64-2009-4K
vagrant up --provider qemu
# Basic Vagrant config (API version 2)
Vagrant.configure(2) do |config|
config.vm.box = "test-box"
config.vm.box_url = "file:///Users/xxx/test.box"
config.vm.box_check_update = false
end
# Basic Vagrant config (API version 2)
Vagrant.configure(2) do |config|
config.vm.provider "qemu" do |qe, override|
override.ssh.username = "xxx"
override.ssh.password = "vagrant"
qe.image_path = "/Users/xxx/test.qcow2"
end
end
Vagrant.configure(2) do |config|
config.vm.box = "centos/7"
config.vm.provider "qemu" do |qe|
qe.arch = "x86_64"
qe.machine = "q35"
qe.cpu = "qemu64"
qe.net_device = "virtio-net-pci"
end
end
# Basic Vagrant config (API version 2)
Vagrant.configure(2) do |config|
# ... other stuff
config.vm.network "forwarded_port", guest: 80, host: 8080
end
Thanks to taraszka for providing this config.
Vagrant.configure("2") do |config|
config.vm.box = "centos/7"
config.vm.provider "qemu" do |qe|
qe.arch = "x86_64"
qe.machine = "q35"
qe.cpu = "max"
qe.smp = "cpus=2,sockets=1,cores=2,threads=1"
qe.net_device = "virtio-net-pci"
qe.extra_qemu_args = %w(-accel tcg,thread=multi,tb-size=512)
qe.qemu_dir = "/usr/local/share/qemu"
end
end
Vagrant.configure("2") do |config|
config.vm.box = "debian/bullseye64"
config.vm.provider "qemu" do |qe|
qe.extra_netdev_args = "net=192.168.51.0/24,dhcpstart=192.168.51.10"
end
end
Windows version QEMU doesn't support daemonize
mode and unix socket
(Notes: not tested)
Vagrant.configure("2") do |config|
# ... other stuff
config.vm.provider "qemu" do |qe|
qe.no_daemonize = true
qe.control_port = 33333
qe.debug_port = 33334
end
end
Serial port is exported to unix socket: <user_home>/.vagrant.d/tmp/vagrant-qemu/<id>/qemu_socket_serial
, or debug_port
.
To debug and login to the GuestOS from serial port:
.vagrant/machines/default/qemu/id
in same directory with Vagrantfile
qemu_socket_serial
nc
to connect: nc -U /Users/.../qemu_socket_serial
debug_port
(for example: 33334)
nc
to connect: nc localhost 33334
To send ctrl+c to GuestOS from nc
, try:
echo 03 | xxd -r -p | nc -U /Users/.../qemu_socket_serial
debug_port
(for example: 33334)
echo 03 | xxd -r -p | nc localhost 33334
To build the vagrant-qemu
plugin, clone this repository out, and use
Bundler to get the dependencies:
bundle
Once you have the dependencies, build with rake
:
bundle exec rake build
We couldn't detect an IP address that was routable to this
machine from the guest machine! Please verify networking is properly
setup in the guest machine and that it is able to access this
host.
As another option, you can manually specify an IP for the machine
to mount from using the `smb_host` option to the synced folder.
The reason is that the user mode of qemu currently in use does not support ping.
smb_host
needs to be explicitly specified. For example:
Vagrant.configure("2") do |config|
# ... other stuff
config.vm.synced_folder ".", "/vagrant", type: "smb", smb_host: "10.0.2.2"
end
I had netcat installed through home brew and it does not support the -U parameter.
I fixed it by uninstalling netcat in home brew brew uninstall netcat
Thanks @kjeldahl fix this at issue #6
If you get this error when running vagrant up
vagrant up
againThis may cause by invalid default qemu dir (/opt/homebrew/share/qemu
).
You can find the correct one by:
echo `brew --prefix`/share/qemu
And then set it (for example /usr/local/share/qemu
) in the Vagrantfile
as:
config.vm.provider "qemu" do |qe|
qe.qemu_dir = "/usr/local/share/qemu"
end