Vagrant VM Runner


ricktap

Recommended Posts

Hi,

 

I'm in the planning phase of building a vagrant provider plugin, that allows me to run my virtual machines inside of unraid (on demand creation and deletion).

 

The idea is to use "vagrant up --provider unraid" on my laptop (or any PC/Mac for that matter) and have the VM start on top of unraid as it would on virtualbox otherwise. This way I can have multiple VMs up without using up all my local RAM on the laptop, but still enjoy all the benefits of a VM.

 

If anyone is undertaking a similar expedition I would greatly appreciate a joined approach, to speed up the development.

Any information on known apis that I could hook into would also be fantastic, as it would reduce the amount of steps I would have to undertake, by taking a low level route.

 

Cheers ricktap

  • Upvote 2
Link to comment
  • 3 years later...
  • 2 years later...

Hi 👋,

I did some experiments in this area I would like to share with you. Having the ability to provision VMs automatically within Unraid given user-specific seed configurations would be awesome. Here is what I did:

 

Disclaimer: Do not experiment with your productive environment. The commands listed are not complete neither fully tested. The setup is a proof of concept. Execute at your own risk. Read the 'Open Issues' section first.

 

The setup utilizes the vagrant libvirt plugin with a local vagrant installation. The Vagrantfile configures a libvirt based base box with Unraid like KVM options (attention: the configuration is incomplete and has side-effects. See below.).

 

Native plugin installation on Ubuntu 22.04. There is also a docker container having all dependencies included already.

# See: https://vagrant-libvirt.github.io/vagrant-libvirt/installation.html
$ sudo apt-get purge vagrant-libvirt
$ sudo apt-mark hold vagrant-libvirt
$ sudo apt-get install -y qemu libvirt-daemon-system ebtables libguestfs-tools
$ sudo apt-get install -y vagrant ruby-fog-libvirt
$ vagrant plugin install vagrant-libvirt

# Create the VM on the remote Unraid server
$ vagrant up

# Destroy the VM. Note the image remains in /var/lib/libvirt/images!
$ vagrant destroy

 

The Vagrantfile below configures only a small portion of what the original Unraid template contains e.g. the network configuration is missing entirely.

Spoiler
# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.require_version ">= 1.8.0"

ENV['VAGRANT_DEFAULT_PROVIDER'] = 'libvirt'
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

  config.vm.define "ubuntu-01" do |config|
  # See: https://app.vagrantup.com/boxes/search?provider=libvirt
  config.vm.hostname = "ubuntu-01"
  config.vm.box = "generic/ubuntu2004"
  config.vm.box_check_update = false

  config.vm.provider :libvirt do |v|
        v.description = "Ubuntu-01 Vagrant"
        v.memory = 1024
        v.cpus = 2
        v.memorybacking :nosharepages
        v.features = ['acpi', 'apic']
        v.cpu_mode = "host-passthrough"

        # <clock/>
        v.clock_offset = "utc"
        v.clock_timer :name => 'rtc', :tickpolicy => 'catchup'
        v.clock_timer :name => 'pit', :tickpolicy => 'delay'
        v.clock_timer :name => 'hpet', :present => 'no'

        v.emulator_path = "/usr/local/sbin/qemu"

        # <channel/>
        v.channel :type => 'unix', :target_name => 'org.qemu.guest_agent.0', :disabled => true

        # <graphics/>
        v.graphics_type = "vnc"
        v.graphics_port = "-1"
        # Available once the pull request is merged
        # See: https://github.com/vagrant-libvirt/vagrant-libvirt/pull/1672
        # v.graphics_websocket = "-1"
        v.graphics_ip = "0.0.0.0"

        # <video/>
        v.video_type = "qxl"
        v.video_vram = "16384"

        # See: https://vagrant-libvirt.github.io/vagrant-libvirt/configuration.html#connection-options
        v.host = "<unraid-server-ip>"
        v.username = "root"
        v.id_ssh_key_file = "/home/<user>/.ssh/id_rsa_unraid"
    end
  end
end

 

 

Unraid lists the VM after bootstrapping in the VM section. You can also verify this by executing the command "virsh list --all". Right now, we cannot access the VM via the internal VNC viewer because the libvirt plugin does not support the websocket attribute (yet!). I am working on contributing this feature to the project. For now, you can manually edit the XML template and add the attribute "websocket = '5600'" to the graphics tag.

 

Open Issues:

  • The VNC viewer does not work, because the vagrant libvirt plugin does not support the websocket attribute (working on a contribution)
  • Vagrant stores the image in "/var/lib/libvirt/images/" which is the default libvirt storage location. This configuration option comes from "/etc/libvirt/storage/default.xml". Changing the default storage location to "/mnt/user/domains" involves probably the Unraid team. Creating another storage pool and referencing it with "storage_pool_name" in the Vagrantfile is possible, but does not survive a reboot.
  • I haven't touched the network configuration yet. At the moment, the proof of concept creates a dedicated network 'vagrant-libvirt' (see "virsh net-list --all")

 

Discussion:

 

After I did these initial tests, I don't know if it is worth the effort. It may be simpler to keep a golden master VM and copy its disks and VM template. There are also not a lot of libvirt vagrant boxes publicly available. In the end, I am still looking for a better solution to provision new VMs in a cloud like manner (with seed configuration) within Unraid. I would love to hear your ideas or solutions.

Edited by T0a
Link to comment
  • 10 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.