ppggff / vagrant-qemu

Use Vagrant to manage machines using QEMU. Test with Apple Silicon / M1 and CentOS aarch64 image
MIT License
424 stars 33 forks source link

Vagrant QEMU Provider

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

Compatible with

Tested:

Others:

Features

Usage

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:

Box format

Same as vagrant-libvirt version-1:

Configuration

Options

This provider exposes a few provider-specific configuration options:

Usage

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

With nil value

To be able to custom the result qemu command deeply, you can set some config options to nil value to skip related qemu arguments.

With other_default = [], all default arguments will be skipped.

Example

  1. Try with a sample box
vagrant init ppggff/centos-7-aarch64-2009-4K
vagrant up --provider qemu
  1. With a local box
# 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
  1. With a local qcow2
# 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
  1. Work with a x86_64 box (basic 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 = "qemu64"
    qe.net_device = "virtio-net-pci"
  end
end
  1. Forwarded ports
# Basic Vagrant config (API version 2)
Vagrant.configure(2) do |config|
  # ... other stuff

  config.vm.network "forwarded_port", guest: 80, host: 8080
end
  1. Force Multicore (x86)

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
  1. Force Local IP
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
  1. Windows host

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

Debug

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:

To send ctrl+c to GuestOS from nc, try:

Build

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

Known issue / Troubleshooting

1. failed to create shared folder

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

2. netcat does not support the -U parameter

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

3. Vagrant SMB synced folders require the account password to be stored in an NT compatible format

If you get this error when running vagrant up

  1. On your M1 Mac, go to System Preferences > Sharing > File Sharing > Options...
  2. Tick "Share Files and Folders using SMB"
  3. Tick your username
  4. Click Done
  5. Run vagrant up again

4. The box you're using with the QEMU provider ('default') is invalid

This 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

TODO