class VagrantPlugins::ProviderLibvirt::Config
Constants
- ARCH_SUPPORT_CPU
list of architectures that support cpu based on github.com/libvirt/libvirt/tree/master/src/cpu
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.
Forward port with id ‘ssh’
The name of the server, where Libvirtd is running.
internal helper attributes
ID SSH key file
Inputs
Libvirt default network
Configure the memballoon
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 Agent to get ip address
Use QEMU session instead of system
Turn on to prevent hostname conflicts
Redirected devices
Random number device passthrough
serial consoles
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
Configure sysinfo values
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
manually specify URI will supersede 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 224 def initialize @uri = UNSET_VALUE @driver = UNSET_VALUE @host = UNSET_VALUE @port = UNSET_VALUE @connect_via_ssh = UNSET_VALUE @username = UNSET_VALUE @password = UNSET_VALUE @id_ssh_key_file = UNSET_VALUE @socket = UNSET_VALUE @proxy_command = UNSET_VALUE @forward_ssh_port = UNSET_VALUE # forward port with id 'ssh' @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 @management_network_mtu = UNSET_VALUE @management_network_keep = UNSET_VALUE @management_network_driver_iommu = 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 @memtunes = {} @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 @cpu_affinity = UNSET_VALUE @shares = UNSET_VALUE @features = UNSET_VALUE @features_hyperv = UNSET_VALUE @clock_offset = UNSET_VALUE @clock_timers = [] @launchsecurity_data = 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 @disk_address_type = UNSET_VALUE @disk_controller_model = UNSET_VALUE @disk_driver_opts = {} @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_websocket = UNSET_VALUE @graphics_ip = UNSET_VALUE @graphics_passwd = UNSET_VALUE @graphics_gl = UNSET_VALUE @video_type = UNSET_VALUE @video_vram = UNSET_VALUE @video_accel3d = 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 @tpm_version = UNSET_VALUE @sysinfo = UNSET_VALUE @memballoon_enabled = UNSET_VALUE @memballoon_model = UNSET_VALUE @memballoon_pci_bus = UNSET_VALUE @memballoon_pci_slot = UNSET_VALUE @nic_adapter_count = UNSET_VALUE # Boot order @boot_order = [] # Storage @disks = [] @cdroms = [] @floppies = [] # 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 # Use Qemu agent to get ip address @qemu_use_agent = UNSET_VALUE @serials = UNSET_VALUE # internal options to help override behaviour @host_device_exclude_prefixes = UNSET_VALUE end
Public Instance Methods
# File lib/vagrant-libvirt/config.rb, line 848 def _default_uri # Determine if any settings except driver provided explicitly, if not # and the LIBVIRT_DEFAULT_URI var is set, use that. # # Skipping driver because that may be set on individual boxes rather # than by the user. if [ @connect_via_ssh, @host, @username, @password, @id_ssh_key_file, @qemu_use_session, @socket, ].none?{ |v| v != UNSET_VALUE } if ENV.fetch('LIBVIRT_DEFAULT_URI', '') != "" @uri = ENV['LIBVIRT_DEFAULT_URI'] end end end
# File lib/vagrant-libvirt/config.rb, line 427 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 866 def _generate_uri(qemu_use_session) # 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 # turn on ssh if an ssh key file is explicitly provided if @connect_via_ssh == UNSET_VALUE && @id_ssh_key_file && @id_ssh_key_file != UNSET_VALUE @connect_via_ssh = true end params = {} if @connect_via_ssh == true finalize_id_ssh_key_file uri += '+ssh://' uri += "#{URI.encode_www_form_component(@username)}@" if @username && @username != UNSET_VALUE uri += (@host && @host != UNSET_VALUE ? @host : 'localhost') params['no_verify'] = '1' params['keyfile'] = @id_ssh_key_file if @id_ssh_key_file else uri += '://' uri += @host if @host && @host != UNSET_VALUE end uri += virt_path # set path to Libvirt socket params['socket'] = @socket if @socket uri += '?' + params.map { |pair| pair.join('=') }.join('&') unless params.empty? uri end
# File lib/vagrant-libvirt/config.rb, line 390 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 409 def _get_floppy_dev(floppies) exist = Hash[floppies.collect { |x| [x[:dev], true] }] # fda - fdb curr = 'a'.ord while curr <= 'b'.ord dev = "fd#{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 two floppies may be attached at a time' end
# File lib/vagrant-libvirt/config.rb, line 741 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 = { type: 'raw', bus: 'ide', path: nil }.merge(options) cdrom = { type: options[:type], dev: options[:dev], bus: options[:bus], path: options[:path] } @cdroms << cdrom end
# File lib/vagrant-libvirt/config.rb, line 790 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], address_type: options[:address_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], io: options[:io], copy_on_read: options[:copy_on_read], discard: options[:discard], detect_zeroes: options[:detect_zeroes], pool: options[:pool], # overrides storage_pool setting for additional disks wwn: options[:wwn], } @disks << disk # append end
# File lib/vagrant-libvirt/config.rb, line 768 def _handle_floppy_storage(options = {}) # <disk type='file' device='floppy'> # <source file='/var/lib/libvirt/images/floppy.vfd'/> # <target dev='fda' bus='fdc'/> # </disk> # # note the target dev will need to be changed with each floppy drive (fda or fdb) options = { bus: 'fdc', path: nil }.merge(options) floppy = { dev: options[:dev], bus: options[:bus], path: options[:path] } @floppies << floppy end
# File lib/vagrant-libvirt/config.rb, line 917 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 386 def boot(device) @boot_order << device # append end
# File lib/vagrant-libvirt/config.rb, line 483 def clock_timer(options = {}) if options[:name].nil? raise 'Clock timer name must be specified' end options.each do |key, value| case key when :name, :track, :tickpolicy, :frequency, :mode, :present if value.nil? raise "Value of timer option #{key} is nil" end else raise "Unknown clock timer option: #{key}" end end @clock_timers.push(options.dup) end
# File lib/vagrant-libvirt/config.rb, line 451 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 516 def cpuaffinitiy(affinity = {}) if @cpu_affinity == UNSET_VALUE @cpu_affinity = {} end affinity.each do |vcpu, cpuset| @cpu_affinity[vcpu] = cpuset end end
# File lib/vagrant-libvirt/config.rb, line 502 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
Disk driver options for primary disk
# File lib/vagrant-libvirt/config.rb, line 722 def disk_driver(options = {}) supported_opts = [:cache, :io, :copy_on_read, :discard, :detect_zeroes] @disk_driver_opts = options.select { |k,_| supported_opts.include? k } end
# File lib/vagrant-libvirt/config.rb, line 925 def finalize! _default_uri if @uri == UNSET_VALUE # settings which _generate_uri @driver = 'kvm' if @driver == UNSET_VALUE @password = nil if @password == UNSET_VALUE @socket = nil if @socket == 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 finalize_from_uri finalize_proxy_command # forward port with id 'ssh' @forward_ssh_port = false if @forward_ssh_port == 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 @management_network_mtu = nil if @management_network_mtu == UNSET_VALUE @management_network_keep = false if @management_network_keep == UNSET_VALUE @management_network_driver_iommu = false if @management_network_driver_iommu == UNSET_VALUE # Domain specific settings. @title = '' if @title == UNSET_VALUE @description = '' if @description == UNSET_VALUE @uuid = '' if @uuid == UNSET_VALUE @machine_type = nil if @machine_type == UNSET_VALUE @machine_arch = nil if @machine_arch == 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 = if @cpu_mode == UNSET_VALUE # only some architectures support the cpu element if @machine_arch.nil? || ARCH_SUPPORT_CPU.include?(@machine_arch.downcase) 'host-model' else nil end else @cpu_mode end @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_affinity = {} if @cpu_affinity == 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 @clock_offset = 'utc' if @clock_offset == UNSET_VALUE @clock_timers = [] if @clock_timers == UNSET_VALUE @launchsecurity_data = nil if @launchsecurity_data == UNSET_VALUE @numa_nodes = @numa_nodes == UNSET_VALUE ? nil : _generate_numa @loader = nil if @loader == UNSET_VALUE @nvram = nil if @nvram == UNSET_VALUE @machine_virtual_size = nil if @machine_virtual_size == UNSET_VALUE @disk_device = @disk_bus == 'scsi' ? 'sda' : 'vda' if @disk_device == UNSET_VALUE @disk_bus = @disk_device.start_with?('sd') ? 'scsi' : 'virtio' if @disk_bus == UNSET_VALUE if @disk_controller_model == UNSET_VALUE if @disk_bus == 'scsi' or @disk_device.start_with?('sd') == 'sd' @disk_controller_model = 'virtio-scsi' else @disk_controller_model = nil end end @disk_address_type = nil if @disk_address_type == UNSET_VALUE @disk_driver_opts = {} if @disk_driver_opts == UNSET_VALUE @nic_model_type = nil if @nic_model_type == UNSET_VALUE @nested = false if @nested == UNSET_VALUE @volume_cache = nil if @volume_cache == UNSET_VALUE @kernel = nil if @kernel == UNSET_VALUE @cmd_line = '' if @cmd_line == UNSET_VALUE @initrd = nil if @initrd == UNSET_VALUE @dtb = nil if @dtb == UNSET_VALUE @graphics_type = 'vnc' if @graphics_type == UNSET_VALUE @graphics_autoport = @graphics_type != 'spice' && @graphics_port == UNSET_VALUE ? 'yes' : nil if (@graphics_type != 'vnc' && @graphics_type != 'spice') || @graphics_passwd == UNSET_VALUE @graphics_passwd = nil end @graphics_port = @graphics_type == 'spice' ? nil : -1 if @graphics_port == UNSET_VALUE @graphics_websocket = @graphics_type == 'spice' ? nil : -1 if @graphics_websocket == UNSET_VALUE @graphics_ip = @graphics_type == 'spice' ? nil : '127.0.0.1' if @graphics_ip == UNSET_VALUE @video_accel3d = false if @video_accel3d == UNSET_VALUE @graphics_gl = @video_accel3d if @graphics_gl == UNSET_VALUE @video_type = @video_accel3d ? 'virtio' : 'cirrus' if @video_type == UNSET_VALUE @video_vram = 16384 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 @tpm_version = nil if @tpm_version == UNSET_VALUE @memballoon_enabled = nil if @memballoon_enabled == UNSET_VALUE @memballoon_model = 'virtio' if @memballoon_model == UNSET_VALUE @memballoon_pci_bus = '0x00' if @memballoon_pci_bus == UNSET_VALUE @memballoon_pci_slot = '0x0f' if @memballoon_pci_slot == UNSET_VALUE @nic_adapter_count = 8 if @nic_adapter_count == UNSET_VALUE @emulator_path = nil if @emulator_path == UNSET_VALUE @sysinfo = {} if @sysinfo == UNSET_VALUE # Boot order @boot_order = [] if @boot_order == UNSET_VALUE # Storage @disks = [] if @disks == UNSET_VALUE @cdroms = [] if @cdroms == UNSET_VALUE @cdroms.map! do |cdrom| cdrom[:dev] = _get_cdrom_dev(@cdroms) if cdrom[:dev].nil? cdrom end @floppies = [] if @floppies == UNSET_VALUE @floppies.map! do |floppy| floppy[:dev] = _get_floppy_dev(@floppies) if floppy[:dev].nil? floppy end # Inputs @inputs = [{ type: 'mouse', bus: 'ps2' }] if @inputs == UNSET_VALUE # Channels @channels = [] if @channels == UNSET_VALUE if @qemu_use_agent == true if @channels.all? { |channel| !channel.fetch(:target_name, '').start_with?('org.qemu.guest_agent.') } channel(:type => 'unix', :target_name => 'org.qemu.guest_agent.0', :target_type => 'virtio') end end if @graphics_type == 'spice' if @channels.all? { |channel| !channel.fetch(:target_name, '').start_with?('com.redhat.spice.') } channel(:type => 'spicevmc', :target_name => 'com.redhat.spice.0', :target_type => 'virtio') end end # filter channels of anything explicitly disabled so it's possible to inject an entry to # avoid the automatic addition of the guest_agent above, and disable it from subsequent use. @channels = @channels.reject { |channel| channel[:disabled] }.tap {|channel| channel.delete(:disabled) } # 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 device passthrough @usbs = [] if @usbs == UNSET_VALUE # Redirected devices @redirdevs = [] if @redirdevs == UNSET_VALUE @redirfilters = [] if @redirfilters == UNSET_VALUE # USB controller if @usbctl_dev == UNSET_VALUE @usbctl_dev = if !@usbs.empty? or !@redirdevs.empty? then {:model => 'qemu-xhci'} else {} end end # 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 @qemu_use_agent = false if @qemu_use_agent == UNSET_VALUE @serials = [{:type => 'pty', :source => nil}] if @serials == UNSET_VALUE @host_device_exclude_prefixes = ['docker', 'macvtap', 'virbr', 'vnet'] if @host_device_exclude_prefixes == UNSET_VALUE end
# File lib/vagrant-libvirt/config.rb, line 462 def hyperv_feature(options = {}) if options[:name].nil? || options[:state].nil? raise 'Feature name AND state must be specified' end if options[:name] == 'spinlocks' && options[:retries].nil? raise 'Feature spinlocks requires retries parameter' end @features_hyperv = [] if @features_hyperv == UNSET_VALUE if options[:name] == 'spinlocks' @features_hyperv.push(name: options[:name], state: options[:state], retries: options[:retries]) else @features_hyperv.push(name: options[:name], state: options[:state]) end end
# File lib/vagrant-libvirt/config.rb, line 572 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 560 def launchsecurity(options = {}) if options.fetch(:type) != 'sev' raise "Launch security type only supports SEV. Explicitly set 'sev' as a type" end @launchsecurity_data = {} @launchsecurity_data[:type] = options[:type] @launchsecurity_data[:cbitpos] = options[:cbitpos] || 47 @launchsecurity_data[:reducedPhysBits] = options[:reducedPhysBits] || 1 @launchsecurity_data[:policy] = options[:policy] || "0x0003" end
# File lib/vagrant-libvirt/config.rb, line 526 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 541 def memtune(config={}) if config[:type].nil? raise "Missing memtune type" end unless ['hard_limit', 'soft_limit', 'swap_hard_limit'].include? config[:type] raise "Memtune type '#{config[:type]}' not allowed (hard_limit, soft_limit, swap_hard_limit are allowed)" end if config[:value].nil? raise "Missing memtune value" end opts = config[:options] || {} opts[:unit] = opts[:unit] || "KiB" @memtunes[config[:type]] = { value: config[:value], config: opts } end
# File lib/vagrant-libvirt/config.rb, line 1258 def merge(other) super.tap do |result| result.boot_order = other.boot_order != [] ? other.boot_order : boot_order c = disks.dup c += other.disks result.disks = c c = cdroms.dup c += other.cdroms result.cdroms = c c = floppies.dup c += other.floppies result.floppies = c result.memtunes = memtunes.merge(other.memtunes) result.disk_driver_opts = disk_driver_opts.merge(other.disk_driver_opts) result.inputs = inputs != UNSET_VALUE ? inputs.dup + (other.inputs != UNSET_VALUE ? other.inputs : []) : other.inputs c = sysinfo == UNSET_VALUE ? {} : sysinfo.dup c.merge!(other.sysinfo) { |_k, x, y| x.respond_to?(:each_pair) ? x.merge(y) : x + y } if other.sysinfo != UNSET_VALUE result.sysinfo = c c = clock_timers.dup c += other.clock_timers result.clock_timers = c c = qemu_env != UNSET_VALUE ? qemu_env.dup : {} c.merge!(other.qemu_env) if other.qemu_env != UNSET_VALUE result.qemu_env = c if serials != UNSET_VALUE s = serials.dup s += other.serials result.serials = s end end end
# File lib/vagrant-libvirt/config.rb, line 617 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], guest_domain: options[:guest_domain], guest_bus: options[:guest_bus], guest_slot: options[:guest_slot], guest_function: options[:guest_function]) end
# File lib/vagrant-libvirt/config.rb, line 820 def qemuargs(options = {}) @qemu_args = [] if @qemu_args == UNSET_VALUE @qemu_args << options if options[:value] end
# File lib/vagrant-libvirt/config.rb, line 826 def qemuenv(options = {}) @qemu_env = {} if @qemu_env == UNSET_VALUE @qemu_env.merge!(options) end
# File lib/vagrant-libvirt/config.rb, line 607 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 681 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 689 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 832 def serial(options={}) @serials = [] if @serials == UNSET_VALUE options = { :type => "pty", :source => nil, }.merge(options) serial = { :type => options[:type], :source => options[:source], } @serials << serial end
# File lib/vagrant-libvirt/config.rb, line 701 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 728 def storage(storage_type, options = {}) if storage_type == :file case options[:device] when :cdrom _handle_cdrom_storage(options) when :floppy _handle_floppy_storage(options) else _handle_disk_storage(options) end end end
# File lib/vagrant-libvirt/config.rb, line 667 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 654 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] if options[:ports] end
# File lib/vagrant-libvirt/config.rb, line 1134 def validate(machine) errors = _detected_errors unless @machine_arch.nil? || ARCH_SUPPORT_CPU.include?(@machine_arch.downcase) unsupported = [:cpu_mode, :cpu_model, :nested, :cpu_features, :cpu_topology, :numa_nodes] cpu_support_required_by = unsupported.select { |x| value = instance_variable_get("@#{x.to_s}") next if value.nil? # not set is_bool = !!value == value next if is_bool && !value # boolean and set to false next if !is_bool && value.empty? # not boolean, but empty '', [], {} true } unless cpu_support_required_by.empty? errors << "Architecture #{@machine_arch} does not support /domain/cpu XML, which is required when setting the config options #{cpu_support_required_by.join(", ")}" end end # technically this shouldn't occur, but ensure that if somehow it does, it gets rejected. if @cpu_mode == 'host-passthrough' && @cpu_model != '' errors << "cannot set cpu_model with cpu_mode of 'host-passthrough'. leave model unset or switch mode." end unless @cpu_model != '' || @cpu_features.empty? errors << "cannot set cpu_features with cpu_model unset, please set a model or skip setting features." end # 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 unless @qemu_use_agent == true || @qemu_use_agent == false errors << "libvirt.qemu_use_agent must be a boolean." end if !@nvram.nil? && @loader.nil? errors << "use of 'nvram' requires a 'loader' to be specified, please add one to the configuration" end if @qemu_use_agent == true # if qemu agent is used to obtain domain ip configuration, at least # one qemu channel has to be configured. As there are various options, # error out and leave configuration to the user unless machine.provider_config.channels.any? { |channel| channel[:target_name].start_with?("org.qemu.guest_agent") } errors << "qemu agent option enabled, but no qemu agent channel configured: please add at least one qemu agent channel to vagrant config" 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.provider_config.serials.each do |serial| if serial[:source] and serial[:source][:path].nil? errors << "serial :source requires :path to be defined" end end # this won't be able to fully resolve the disks until the box has # been downloaded and any devices that need to be assigned to the # disks contained have been allocated disk_resolver = ::VagrantPlugins::ProviderLibvirt::Util::DiskDeviceResolver.new begin disk_resolver.resolve(machine.provider_config.disks) rescue Errors::VagrantLibvirtError => e errors << "#{e}" end machine.config.vm.networks.each_with_index do |network, index| type, opts = network if opts[:mac] if opts[:mac] =~ /\A([0-9a-fA-F]{12})\z/ opts[:mac] = opts[:mac].scan(/../).join(':') end unless opts[:mac] =~ /\A([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})\z/ errors << "Configured NIC MAC '#{opts[:mac]}' is not in 'xx:xx:xx:xx:xx:xx' or 'xxxxxxxxxxxx' format" end end # only interested in public networks where portgroup is nil, as then source will be a host device if type == :public_network && opts[:portgroup] == nil devices = host_devices(machine) hostdev = opts.fetch(:dev, 'eth0') if !devices.include?(hostdev) errors << "network configuration #{index} for machine #{machine.name} is a public_network referencing host device '#{hostdev}' which does not exist, consider adding ':dev => ....' referencing one of #{devices.join(", ")}" end end end if !machine.provider_config.volume_cache.nil? and machine.provider_config.volume_cache != UNSET_VALUE machine.ui.warn("Libvirt Provider: volume_cache is deprecated. Use disk_driver :cache => '#{machine.provider_config.volume_cache}' instead.") if !machine.provider_config.disk_driver_opts.empty? machine.ui.warn("Libvirt Provider: volume_cache has no effect when disk_driver is defined.") end end # if run via a session, then qemu will be run with user permissions, make sure the user # has permissions to access the host paths otherwise there will be an error triggered if machine.provider_config.qemu_use_session synced_folders(machine).fetch(:"9p", []).each do |_, options| unless File.readable?(options[:hostpath]) errors << "9p synced_folder cannot mount host path #{options[:hostpath]} into guest #{options[:guestpath]} when using qemu session as executing user does not have permissions to read the directory on the user." end end unless synced_folders(machine)[:"virtiofs"].nil? machine.ui.warn("Note: qemu session may not support virtiofs for synced_folders, use 9p or enable use of qemu:///system context unless you know what you are doing") end end errors = validate_sysinfo(machine, errors) { 'Libvirt Provider' => errors } end
# File lib/vagrant-libvirt/config.rb, line 640 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
Private Instance Methods
# File lib/vagrant-libvirt/config.rb, line 1302 def finalize_from_uri # Parse uri to extract individual components uri = _parse_uri(@uri) system_uri = uri.dup system_uri.path = '/system' @system_uri = system_uri.to_s if @system_uri == UNSET_VALUE # only set @connect_via_ssh if not explicitly to avoid overriding # and allow an error to occur if the @uri and @connect_via_ssh disagree @connect_via_ssh = uri.scheme.include? "ssh" if @connect_via_ssh == UNSET_VALUE # Set qemu_use_session based on the URI if it wasn't set by the user if @qemu_use_session == UNSET_VALUE if (uri.scheme.start_with? "qemu") && (uri.path.include? "session") @qemu_use_session = true else @qemu_use_session = false end end # Extract host values from uri if provided, otherwise set empty string @host = uri.host || "" @port = uri.port # only override username if there is a value provided @username = nil if @username == UNSET_VALUE @username = uri.user if uri.user if uri.query params = CGI.parse(uri.query) @id_ssh_key_file = params['keyfile'].first if params.has_key?('keyfile') end finalize_id_ssh_key_file end
# File lib/vagrant-libvirt/config.rb, line 1345 def finalize_id_ssh_key_file # resolve based on the following roles # 1) if @connect_via_ssh is set to true, and id_ssh_key_file not current set, # set default if the file exists # 2) if supplied the key name, attempt to expand based on user home # 3) otherwise set to nil if @connect_via_ssh == true && @id_ssh_key_file == UNSET_VALUE # set default if using ssh while allowing a user using nil to disable this id_ssh_key_file = resolve_ssh_key_file('id_rsa') id_ssh_key_file = nil if !File.file?(id_ssh_key_file) elsif @id_ssh_key_file != UNSET_VALUE id_ssh_key_file = resolve_ssh_key_file(@id_ssh_key_file) else id_ssh_key_file = nil end @id_ssh_key_file = id_ssh_key_file end
# File lib/vagrant-libvirt/config.rb, line 1365 def finalize_proxy_command if @connect_via_ssh if @proxy_command == UNSET_VALUE proxy_command = "ssh '#{@host}' " proxy_command += "-p #{@port} " if @port proxy_command += "-l '#{@username}' " if @username proxy_command += "-i '#{@id_ssh_key_file}' " if @id_ssh_key_file proxy_command += '-W %h:%p' else inputs = { host: @host } inputs << { port: @port } if @port inputs[:username] = @username if @username inputs[:id_ssh_key_file] = @id_ssh_key_file if @id_ssh_key_file proxy_command = String.new(@proxy_command) # avoid needing to escape '%' symbols inputs.each do |key, value| proxy_command.gsub!("{#{key}}", value) end end @proxy_command = proxy_command else @proxy_command = nil end end
# File lib/vagrant-libvirt/config.rb, line 1392 def host_devices(machine) machine.provider.driver.host_devices.select do |dev| next if dev.empty? dev != "lo" && !@host_device_exclude_prefixes.any? { |exclude| dev.start_with?(exclude) } end end
# File lib/vagrant-libvirt/config.rb, line 1337 def resolve_ssh_key_file(key_file) # set ssh key for access to Libvirt host # if no slash, prepend $HOME/.ssh/ key_file = "#{ENV['HOME']}/.ssh/#{key_file}" if key_file && key_file !~ /\A\// key_file end
# File lib/vagrant-libvirt/config.rb, line 1399 def validate_sysinfo(machine, errors) valid_sysinfo = { 'bios' => %w[vendor version date release], 'system' => %w[manufacturer product version serial uuid sku family], 'base board' => %w[manufacturer product version serial asset location], 'chassis' => %w[manufacturer version serial asset sku], 'oem strings' => nil, } machine.provider_config.sysinfo.each_pair do |block_name, entries| block_name = block_name.to_s unless valid_sysinfo.key?(block_name) errors << "invalid sysinfo element '#{block_name}'; smbios sysinfo elements supported: #{valid_sysinfo.keys.join(', ')}" next end if valid_sysinfo[block_name].nil? # assume simple array of text entries entries.each do |entry| if entry.respond_to?(:to_str) if entry.to_s.empty? machine.ui.warn("Libvirt Provider: 'sysinfo.#{block_name}' contains an empty or nil entry and will be discarded") end else errors << "sysinfo.#{block_name} expects entries to be stringy, got #{entry.class} containing '#{entry}'" end end else entries.each_pair do |entry_name, entry_text| entry_name = entry_name.to_s unless valid_sysinfo[block_name].include?(entry_name) errors << "'sysinfo.#{block_name}' does not support entry name '#{entry_name}'; entries supported: #{valid_sysinfo[block_name].join(', ')}" next end # this allows removal of entries specified by other Vagrantfile's in the hierarchy if entry_text.to_s.empty? machine.ui.warn("Libvirt Provider: sysinfo.#{block_name}.#{entry_name} is nil or empty and therefore has no effect.") end end end end errors end