class VagrantPlugins::ProviderLibvirt::Config
Attributes
Autostart
Channels
If use ssh tunnel to connect to Libvirt.
Default host prefix (alternative to use project folder name)
Storage
A hypervisor name to access via Libvirt.
The name of the server, where Libvirtd is running.
ID SSH key file
Inputs
Libvirt default network
Attach mgmt network
Sets the max number of NICs that can be created Default set to 8. Don't change the default unless you know what are doing
Password for Libvirt connection.
PCI device passthrough
Additional qemuargs arguments
Additional qemuenv arguments
Use QEMU session instead of system
Turn on to prevent hostname conflicts
Redirected devices
Random number device passthrough
smartcard device
Libvirt storage pool where the base image snapshot shall be stored
Path towards the Libvirt socket
Libvirt storage pool name, where box image and instance snapshots will be stored.
Suspend mode
System connection information
Domain specific settings used while creating new domain.
Sets the information for connecting to a host TPM device Only supports socket-based TPMs
will supercede most other options if provided
USB controller
USB device passthrough
The username to access Libvirt.
Watchdog device
Public Class Methods
# File lib/vagrant-libvirt/config.rb, line 176 def initialize @uri = UNSET_VALUE @driver = UNSET_VALUE @host = UNSET_VALUE @connect_via_ssh = UNSET_VALUE @username = UNSET_VALUE @password = UNSET_VALUE @id_ssh_key_file = UNSET_VALUE @storage_pool_name = UNSET_VALUE @snapshot_pool_name = UNSET_VALUE @random_hostname = UNSET_VALUE @management_network_device = UNSET_VALUE @management_network_name = UNSET_VALUE @management_network_address = UNSET_VALUE @management_network_mode = UNSET_VALUE @management_network_mac = UNSET_VALUE @management_network_guest_ipv6 = UNSET_VALUE @management_network_autostart = UNSET_VALUE @management_network_pci_slot = UNSET_VALUE @management_network_pci_bus = UNSET_VALUE @management_network_domain = UNSET_VALUE # System connection information @system_uri = UNSET_VALUE # Domain specific settings. @title = UNSET_VALUE @description = UNSET_VALUE @uuid = UNSET_VALUE @memory = UNSET_VALUE @nodeset = UNSET_VALUE @memory_backing = UNSET_VALUE @cpus = UNSET_VALUE @cpuset = UNSET_VALUE @cpu_mode = UNSET_VALUE @cpu_model = UNSET_VALUE @cpu_fallback = UNSET_VALUE @cpu_features = UNSET_VALUE @cpu_topology = UNSET_VALUE @shares = UNSET_VALUE @features = UNSET_VALUE @features_hyperv = UNSET_VALUE @numa_nodes = UNSET_VALUE @loader = UNSET_VALUE @nvram = UNSET_VALUE @machine_type = UNSET_VALUE @machine_arch = UNSET_VALUE @machine_virtual_size = UNSET_VALUE @disk_bus = UNSET_VALUE @disk_device = UNSET_VALUE @nic_model_type = UNSET_VALUE @nested = UNSET_VALUE @volume_cache = UNSET_VALUE @kernel = UNSET_VALUE @initrd = UNSET_VALUE @dtb = UNSET_VALUE @cmd_line = UNSET_VALUE @emulator_path = UNSET_VALUE @graphics_type = UNSET_VALUE @graphics_autoport = UNSET_VALUE @graphics_port = UNSET_VALUE @graphics_ip = UNSET_VALUE @graphics_passwd = UNSET_VALUE @video_type = UNSET_VALUE @video_vram = UNSET_VALUE @sound_type = UNSET_VALUE @keymap = UNSET_VALUE @kvm_hidden = UNSET_VALUE @tpm_model = UNSET_VALUE @tpm_type = UNSET_VALUE @tpm_path = UNSET_VALUE @nic_adapter_count = UNSET_VALUE # Boot order @boot_order = [] # Storage @disks = [] @cdroms = [] # Inputs @inputs = UNSET_VALUE # Channels @channels = UNSET_VALUE # PCI device passthrough @pcis = UNSET_VALUE # Random number device passthrough @rng = UNSET_VALUE # Watchdog device @watchdog_dev = UNSET_VALUE # USB controller @usbctl_dev = UNSET_VALUE # USB device passthrough @usbs = UNSET_VALUE # Redirected devices @redirdevs = UNSET_VALUE @redirfilters = UNSET_VALUE # smartcard device @smartcard_dev = UNSET_VALUE # Suspend mode @suspend_mode = UNSET_VALUE # Autostart @autostart = UNSET_VALUE # Attach mgmt network @mgmt_attach = UNSET_VALUE # Additional QEMU commandline arguments @qemu_args = UNSET_VALUE # Additional QEMU commandline environment variables @qemu_env = UNSET_VALUE @qemu_use_session = UNSET_VALUE end
Public Instance Methods
# File lib/vagrant-libvirt/config.rb, line 336 def _generate_numa @numa_nodes.collect { |x| # Perform some validation of cpu values unless x[:cpus] =~ /^\d+-\d+$/ raise 'numa_nodes[:cpus] must be in format "integer-integer"' end # Convert to KiB x[:memory] = x[:memory].to_i * 1024 } # Grab the value of the last @numa_nodes[:cpus] and verify @cpus matches # Note: [:cpus] is zero based and @cpus is not, so we need to +1 last_cpu = @numa_nodes.last[:cpus] last_cpu = last_cpu.scan(/\d+$/)[0] last_cpu = last_cpu.to_i + 1 if @cpus != last_cpu.to_i raise 'The total number of numa_nodes[:cpus] must equal config.cpus' end @numa_nodes end
code to generate URI from from either the LIBVIRT_URI environment variable or a config moved out of the connect action
# File lib/vagrant-libvirt/config.rb, line 628 def _generate_uri(qemu_use_session) # If the LIBVIRT_DEFAULT_URI var is set, we'll use that if ENV.fetch('LIBVIRT_DEFAULT_URI', '') != "" return ENV['LIBVIRT_DEFAULT_URI'] end # builds the Libvirt connection URI from the given driver config # Setup connection uri. uri = @driver.dup virt_path = case uri when 'qemu', 'kvm' qemu_use_session ? '/session' : '/system' when 'openvz', 'uml', 'phyp', 'parallels' '/system' when '@en', 'esx' '/' when 'vbox', 'vmwarews', 'hyperv' '/session' else raise "Require specify driver #{uri}" end if uri == 'kvm' uri = 'qemu' # use QEMU uri for KVM domain type end if @connect_via_ssh uri << '+ssh://' uri << @username + '@' if @username uri << ( @host ? @host : 'localhost' ) else uri << '://' uri << @host if @host end uri << virt_path params = {'no_verify' => '1'} if @id_ssh_key_file # set ssh key for access to Libvirt host # if no slash, prepend $HOME/.ssh/ @id_ssh_key_file.prepend("#{ENV['HOME']}/.ssh/") if @id_ssh_key_file !~ /\A\// params['keyfile'] = @id_ssh_key_file end # set path to Libvirt socket params['socket'] = @socket if @socket uri << "?" + params.map{|pair| pair.join('=')}.join('&') uri end
# File lib/vagrant-libvirt/config.rb, line 318 def _get_cdrom_dev(cdroms) exist = Hash[cdroms.collect { |x| [x[:dev], true] }] # hda - hdc curr = 'a'.ord while curr <= 'd'.ord dev = 'hd' + curr.chr if exist[dev] curr += 1 next else return dev end end # is it better to raise our own error, or let Libvirt cause the exception? raise 'Only four cdroms may be attached at a time' end
# File lib/vagrant-libvirt/config.rb, line 307 def _get_device(disks) # skip existing devices and also the first one (vda) exist = disks.collect { |x| x[:device] } + [1.vdev.to_s] skip = 1 # we're 1 based, not 0 based... loop do dev = skip.vdev # get lettered device return dev unless exist.include?(dev) skip += 1 end end
# File lib/vagrant-libvirt/config.rb, line 565 def _handle_cdrom_storage(options = {}) # <disk type="file" device="cdrom"> # <source file="/home/user/virtio-win-0.1-100.iso"/> # <target dev="hdc"/> # <readonly/> # <address type='drive' controller='0' bus='1' target='0' unit='0'/> # </disk> # # note the target dev will need to be changed with each cdrom drive (hdc, hdd, etc), # as will the address unit number (unit=0, unit=1, etc) options = { bus: 'ide', path: nil }.merge(options) cdrom = { dev: options[:dev], bus: options[:bus], path: options[:path] } @cdroms << cdrom end
# File lib/vagrant-libvirt/config.rb, line 590 def _handle_disk_storage(options = {}) options = { type: 'qcow2', size: '10G', # matches the fog default path: nil, bus: 'virtio' }.merge(options) disk = { device: options[:device], type: options[:type], size: options[:size], path: options[:path], bus: options[:bus], cache: options[:cache] || 'default', allow_existing: options[:allow_existing], shareable: options[:shareable], serial: options[:serial], wwn: options[:wwn] } @disks << disk # append end
# File lib/vagrant-libvirt/config.rb, line 681 def _parse_uri(uri) begin URI.parse(uri) rescue raise "@uri set to invalid uri '#{uri}'" end end
# File lib/vagrant-libvirt/config.rb, line 303 def boot(device) @boot_order << device # append end
# File lib/vagrant-libvirt/config.rb, line 360 def cpu_feature(options = {}) if options[:name].nil? || options[:policy].nil? raise 'CPU Feature name AND policy must be specified' end @cpu_features = [] if @cpu_features == UNSET_VALUE @cpu_features.push(name: options[:name], policy: options[:policy]) end
# File lib/vagrant-libvirt/config.rb, line 382 def cputopology(options = {}) if options[:sockets].nil? || options[:cores].nil? || options[:threads].nil? raise 'CPU topology must have all of sockets, cores and threads specified' end if @cpu_topology == UNSET_VALUE @cpu_topology = {} end @cpu_topology[:sockets] = options[:sockets] @cpu_topology[:cores] = options[:cores] @cpu_topology[:threads] = options[:threads] end
# File lib/vagrant-libvirt/config.rb, line 689 def finalize! @driver = 'kvm' if @driver == UNSET_VALUE @host = nil if @host == UNSET_VALUE @connect_via_ssh = false if @connect_via_ssh == UNSET_VALUE @username = nil if @username == UNSET_VALUE @password = nil if @password == UNSET_VALUE @id_ssh_key_file = 'id_rsa' if @id_ssh_key_file == UNSET_VALUE @storage_pool_name = 'default' if @storage_pool_name == UNSET_VALUE @snapshot_pool_name = @storage_pool_name if @snapshot_pool_name == UNSET_VALUE @storage_pool_path = nil if @storage_pool_path == UNSET_VALUE @random_hostname = false if @random_hostname == UNSET_VALUE @management_network_device = 'virbr0' if @management_network_device == UNSET_VALUE @management_network_name = 'vagrant-libvirt' if @management_network_name == UNSET_VALUE @management_network_address = '192.168.121.0/24' if @management_network_address == UNSET_VALUE @management_network_mode = 'nat' if @management_network_mode == UNSET_VALUE @management_network_mac = nil if @management_network_mac == UNSET_VALUE @management_network_guest_ipv6 = 'yes' if @management_network_guest_ipv6 == UNSET_VALUE @management_network_autostart = false if @management_network_autostart == UNSET_VALUE @management_network_pci_bus = nil if @management_network_pci_bus == UNSET_VALUE @management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE @management_network_domain = nil if @management_network_domain == UNSET_VALUE @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE # If uri isn't set then let's build one from various sources. # Default to passing false for qemu_use_session if it's not set. if @uri == UNSET_VALUE @uri = _generate_uri(@qemu_use_session == UNSET_VALUE ? false : @qemu_use_session) end # Set qemu_use_session based on the URI if it wasn't set by the user if @qemu_use_session == UNSET_VALUE uri = _parse_uri(@uri) if (uri.scheme.start_with? "qemu") && (uri.path.include? "session") @qemu_use_session = true else @qemu_use_session = false end end # Domain specific settings. @title = '' if @title == UNSET_VALUE @description = '' if @description == UNSET_VALUE @uuid = '' if @uuid == UNSET_VALUE @memory = 512 if @memory == UNSET_VALUE @nodeset = nil if @nodeset == UNSET_VALUE @memory_backing = [] if @memory_backing == UNSET_VALUE @cpus = 1 if @cpus == UNSET_VALUE @cpuset = nil if @cpuset == UNSET_VALUE @cpu_mode = 'host-model' if @cpu_mode == UNSET_VALUE @cpu_model = if (@cpu_model == UNSET_VALUE) && (@cpu_mode == 'custom') 'qemu64' elsif @cpu_mode != 'custom' '' else @cpu_model end @cpu_topology = {} if @cpu_topology == UNSET_VALUE @cpu_fallback = 'allow' if @cpu_fallback == UNSET_VALUE @cpu_features = [] if @cpu_features == UNSET_VALUE @shares = nil if @shares == UNSET_VALUE @features = ['acpi','apic','pae'] if @features == UNSET_VALUE @features_hyperv = [] if @features_hyperv == UNSET_VALUE @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa @loader = nil if @loader == UNSET_VALUE @nvram = nil if @nvram == UNSET_VALUE @machine_type = nil if @machine_type == UNSET_VALUE @machine_arch = nil if @machine_arch == UNSET_VALUE @machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE @disk_bus = 'virtio' if @disk_bus == UNSET_VALUE @disk_device = 'vda' if @disk_device == UNSET_VALUE @nic_model_type = nil if @nic_model_type == UNSET_VALUE @nested = false if @nested == UNSET_VALUE @volume_cache = 'default' if @volume_cache == UNSET_VALUE @kernel = nil if @kernel == UNSET_VALUE @cmd_line = '' if @cmd_line == UNSET_VALUE @initrd = '' if @initrd == UNSET_VALUE @dtb = nil if @dtb == UNSET_VALUE @graphics_type = 'vnc' if @graphics_type == UNSET_VALUE @graphics_autoport = 'yes' if @graphics_port == UNSET_VALUE @graphics_autoport = 'no' if @graphics_port != UNSET_VALUE if (@graphics_type != 'vnc' && @graphics_type != 'spice') || @graphics_passwd == UNSET_VALUE @graphics_passwd = nil end @graphics_port = -1 if @graphics_port == UNSET_VALUE @graphics_ip = '127.0.0.1' if @graphics_ip == UNSET_VALUE @video_type = 'cirrus' if @video_type == UNSET_VALUE @video_vram = 9216 if @video_vram == UNSET_VALUE @sound_type = nil if @sound_type == UNSET_VALUE @keymap = 'en-us' if @keymap == UNSET_VALUE @kvm_hidden = false if @kvm_hidden == UNSET_VALUE @tpm_model = 'tpm-tis' if @tpm_model == UNSET_VALUE @tpm_type = 'passthrough' if @tpm_type == UNSET_VALUE @tpm_path = nil if @tpm_path == UNSET_VALUE @nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE @emulator_path = nil if @emulator_path == UNSET_VALUE # Boot order @boot_order = [] if @boot_order == UNSET_VALUE # Storage @disks = [] if @disks == UNSET_VALUE @disks.map! do |disk| disk[:device] = _get_device(@disks) if disk[:device].nil? disk end @cdroms = [] if @cdroms == UNSET_VALUE @cdroms.map! do |cdrom| cdrom[:dev] = _get_cdrom_dev(@cdroms) if cdrom[:dev].nil? cdrom end # Inputs @inputs = [{ type: 'mouse', bus: 'ps2' }] if @inputs == UNSET_VALUE # Channels @channels = [] if @channels == UNSET_VALUE # PCI device passthrough @pcis = [] if @pcis == UNSET_VALUE # Random number generator passthrough @rng = {} if @rng == UNSET_VALUE # Watchdog device @watchdog_dev = {} if @watchdog_dev == UNSET_VALUE # USB controller @usbctl_dev = {} if @usbctl_dev == UNSET_VALUE # USB device passthrough @usbs = [] if @usbs == UNSET_VALUE # Redirected devices @redirdevs = [] if @redirdevs == UNSET_VALUE @redirfilters = [] if @redirfilters == UNSET_VALUE # smartcard device @smartcard_dev = {} if @smartcard_dev == UNSET_VALUE # Suspend mode @suspend_mode = 'pause' if @suspend_mode == UNSET_VALUE # Autostart @autostart = false if @autostart == UNSET_VALUE # Attach mgmt network @mgmt_attach = true if @mgmt_attach == UNSET_VALUE # Additional QEMU commandline arguments @qemu_args = [] if @qemu_args == UNSET_VALUE # Additional QEMU commandline environment variables @qemu_env = {} if @qemu_env == UNSET_VALUE end
# File lib/vagrant-libvirt/config.rb, line 371 def hyperv_feature(options = {}) if options[:name].nil? || options[:state].nil? raise 'Feature name AND state must be specified' end @features_hyperv = [] if @features_hyperv == UNSET_VALUE @features_hyperv.push(name: options[:name], state: options[:state]) end
# File lib/vagrant-libvirt/config.rb, line 411 def input(options = {}) if options[:type].nil? || options[:bus].nil? raise 'Input type AND bus must be specified' end @inputs = [] if @inputs == UNSET_VALUE @inputs.push(type: options[:type], bus: options[:bus]) end
# File lib/vagrant-libvirt/config.rb, line 396 def memorybacking(option, config = {}) case option when :source raise 'Source type must be specified' if config[:type].nil? when :access raise 'Access mode must be specified' if config[:mode].nil? when :allocation raise 'Allocation mode must be specified' if config[:mode].nil? end @memory_backing = [] if @memory_backing == UNSET_VALUE @memory_backing.push(name: option, config: config) end
# File lib/vagrant-libvirt/config.rb, line 877 def merge(other) super.tap do |result| c = disks.dup c += other.disks result.disks = c c = cdroms.dup c += other.cdroms result.cdroms = c c = qemu_env != UNSET_VALUE ? qemu_env.dup : {} c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE result.qemu_env = c end end
# File lib/vagrant-libvirt/config.rb, line 454 def pci(options = {}) if options[:bus].nil? || options[:slot].nil? || options[:function].nil? raise 'Bus AND slot AND function must be specified. Check `lspci` for that numbers.' end @pcis = [] if @pcis == UNSET_VALUE if options[:domain].nil? pci_domain = '0x0000' else pci_domain = options[:domain] end @pcis.push(domain: pci_domain, bus: options[:bus], slot: options[:slot], function: options[:function]) end
# File lib/vagrant-libvirt/config.rb, line 614 def qemuargs(options = {}) @qemu_args = [] if @qemu_args == UNSET_VALUE @qemu_args << options if options[:value] end
# File lib/vagrant-libvirt/config.rb, line 620 def qemuenv(options = {}) @qemu_env = {} if @qemu_env == UNSET_VALUE @qemu_env.merge!(options) end
# File lib/vagrant-libvirt/config.rb, line 444 def random(options = {}) if !options[:model].nil? && options[:model] != 'random' raise 'The only supported rng backend is "random".' end @rng = {} if @rng == UNSET_VALUE @rng[:model] = options[:model] end
# File lib/vagrant-libvirt/config.rb, line 514 def redirdev(options = {}) raise 'Type must be specified.' if options[:type].nil? @redirdevs = [] if @redirdevs == UNSET_VALUE @redirdevs.push(type: options[:type]) end
# File lib/vagrant-libvirt/config.rb, line 522 def redirfilter(options = {}) raise 'Option allow must be specified.' if options[:allow].nil? @redirfilters = [] if @redirfilters == UNSET_VALUE @redirfilters.push(class: options[:class] || -1, vendor: options[:vendor] || -1, product: options[:product] || -1, version: options[:version] || -1, allow: options[:allow]) end
# File lib/vagrant-libvirt/config.rb, line 534 def smartcard(options = {}) if options[:mode].nil? raise 'Option mode must be specified.' elsif options[:mode] != 'passthrough' raise 'Currently only passthrough mode is supported!' elsif options[:type] == 'tcp' && (options[:source_mode].nil? || options[:source_host].nil? || options[:source_service].nil?) raise 'If using type "tcp", option "source_mode", "source_host" and "source_service" must be specified.' end if @smartcard_dev == UNSET_VALUE @smartcard_dev = {} end @smartcard_dev[:mode] = options[:mode] @smartcard_dev[:type] = options[:type] || 'spicevmc' @smartcard_dev[:source_mode] = options[:source_mode] if @smartcard_dev[:type] == 'tcp' @smartcard_dev[:source_host] = options[:source_host] if @smartcard_dev[:type] == 'tcp' @smartcard_dev[:source_service] = options[:source_service] if @smartcard_dev[:type] == 'tcp' end
NOTE: this will run twice for each time it's needed- keep it idempotent
# File lib/vagrant-libvirt/config.rb, line 555 def storage(storage_type, options = {}) if storage_type == :file if options[:device] == :cdrom _handle_cdrom_storage(options) else _handle_disk_storage(options) end end end
# File lib/vagrant-libvirt/config.rb, line 500 def usb(options = {}) if (options[:bus].nil? || options[:device].nil?) && options[:vendor].nil? && options[:product].nil? raise 'Bus and device and/or vendor and/or product must be specified. Check `lsusb` for these.' end @usbs = [] if @usbs == UNSET_VALUE @usbs.push(bus: options[:bus], device: options[:device], vendor: options[:vendor], product: options[:product], startupPolicy: options[:startupPolicy]) end
# File lib/vagrant-libvirt/config.rb, line 487 def usb_controller(options = {}) if options[:model].nil? raise 'USB controller model must be specified.' end if @usbctl_dev == UNSET_VALUE @usbctl_dev = {} end @usbctl_dev[:model] = options[:model] @usbctl_dev[:ports] = options[:ports] end
# File lib/vagrant-libvirt/config.rb, line 845 def validate(machine) errors = _detected_errors # The @uri and @qemu_use_session should not conflict uri = _parse_uri(@uri) if (uri.scheme.start_with? "qemu") && (uri.path.include? "session") if @qemu_use_session != true errors << "the URI and qemu_use_session configuration conflict: uri:'#{@uri}' qemu_use_session:'#{@qemu_use_session}'" end end machine.provider_config.disks.each do |disk| if disk[:path] && (disk[:path][0] == '/') errors << "absolute volume paths like '#{disk[:path]}' not yet supported" end end machine.config.vm.networks.each do |_type, opts| if opts[:mac] opts[:mac].downcase! if opts[:mac] =~ /\A([0-9a-f]{12})\z/ opts[:mac] = opts[:mac].scan(/../).join(':') end unless opts[:mac] =~ /\A([0-9a-f]{2}:){5}([0-9a-f]{2})\z/ errors << "Configured NIC MAC '#{opts[:mac]}' is not in 'xx:xx:xx:xx:xx:xx' or 'xxxxxxxxxxxx' format" end end end { 'Libvirt Provider' => errors } end
# File lib/vagrant-libvirt/config.rb, line 473 def watchdog(options = {}) if options[:model].nil? raise 'Model must be specified.' end if @watchdog_dev == UNSET_VALUE @watchdog_dev = {} end @watchdog_dev[:model] = options[:model] @watchdog_dev[:action] = options[:action] || 'reset' end