From b0eddf677068b36716f2352cd836aca107fc5cef Mon Sep 17 00:00:00 2001 From: qazokm Date: Thu, 22 Feb 2018 15:52:58 +0800 Subject: [PATCH 1/4] Create storage pools and volumes with correct permissions --- lib/vagrant-libvirt/action.rb | 4 +- .../action/create_domain_volume.rb | 9 +- lib/vagrant-libvirt/action/create_networks.rb | 5 ++ .../action/destroy_networks.rb | 5 ++ .../action/handle_box_image.rb | 82 +++++++++++++++---- .../action/handle_storage_pool.rb | 5 ++ lib/vagrant-libvirt/config.rb | 11 ++- lib/vagrant-libvirt/errors.rb | 4 + .../templates/default_storage_pool.xml.erb | 6 +- .../templates/default_storage_volume.xml.erb | 14 ++++ lib/vagrant-libvirt/util.rb | 1 + lib/vagrant-libvirt/util/storage_util.rb | 27 ++++++ locales/en.yml | 2 + 13 files changed, 147 insertions(+), 28 deletions(-) create mode 100644 lib/vagrant-libvirt/templates/default_storage_volume.xml.erb create mode 100644 lib/vagrant-libvirt/util/storage_util.rb diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb index 146d339..682ef82 100644 --- a/lib/vagrant-libvirt/action.rb +++ b/lib/vagrant-libvirt/action.rb @@ -27,7 +27,7 @@ module VagrantPlugins if !env[:machine].config.vm.box b2.use CreateDomain b2.use CreateNetworks - b2.use CreateNetworkInterfaces + #b2.use CreateNetworkInterfaces b2.use SetBootOrder b2.use StartDomain else @@ -44,7 +44,7 @@ module VagrantPlugins b2.use PrepareNFSSettings b2.use ShareFolders b2.use CreateNetworks - b2.use CreateNetworkInterfaces + #b2.use CreateNetworkInterfaces b2.use SetBootOrder b2.use StartDomain diff --git a/lib/vagrant-libvirt/action/create_domain_volume.rb b/lib/vagrant-libvirt/action/create_domain_volume.rb index 45aa5c2..6633788 100644 --- a/lib/vagrant-libvirt/action/create_domain_volume.rb +++ b/lib/vagrant-libvirt/action/create_domain_volume.rb @@ -8,6 +8,7 @@ module VagrantPlugins # image as new domain volume. class CreateDomainVolume include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate + include VagrantPlugins::ProviderLibvirt::Util::StorageUtil def initialize(app, _env) @logger = Log4r::Logger.new('vagrant_libvirt::action::create_domain_volume') @@ -48,8 +49,8 @@ module VagrantPlugins xml.target do xml.format(type: 'qcow2') xml.permissions do - xml.owner 0 - xml.group 0 + xml.owner storage_uid(env) + xml.group storage_gid(env) xml.mode '0600' xml.label 'virt_image_t' end @@ -58,8 +59,8 @@ module VagrantPlugins xml.path(@backing_file) xml.format(type: 'qcow2') xml.permissions do - xml.owner 0 - xml.group 0 + xml.owner storage_uid(env) + xml.group storage_gid(env) xml.mode '0600' xml.label 'virt_image_t' end diff --git a/lib/vagrant-libvirt/action/create_networks.rb b/lib/vagrant-libvirt/action/create_networks.rb index 5bb6809..f5ee5b5 100644 --- a/lib/vagrant-libvirt/action/create_networks.rb +++ b/lib/vagrant-libvirt/action/create_networks.rb @@ -27,6 +27,11 @@ module VagrantPlugins end def call(env) + if env[:machine].provider_config.qemu_use_session + @app.call(env) + return + end + # only one vm at a time should try to set up networks # otherwise they'll have inconsitent views of current state # and conduct redundant operations that cause errors diff --git a/lib/vagrant-libvirt/action/destroy_networks.rb b/lib/vagrant-libvirt/action/destroy_networks.rb index 9039bb6..ede4c93 100644 --- a/lib/vagrant-libvirt/action/destroy_networks.rb +++ b/lib/vagrant-libvirt/action/destroy_networks.rb @@ -13,6 +13,11 @@ module VagrantPlugins end def call(env) + if env[:machine].provider_config.qemu_use_session + @app.call(env) + return + end + # If there were some networks created for this machine, in machines # data directory, created_networks file holds UUIDs of each network. created_networks_file = env[:machine].data_dir + 'created_networks' diff --git a/lib/vagrant-libvirt/action/handle_box_image.rb b/lib/vagrant-libvirt/action/handle_box_image.rb index a4f2255..990ea7d 100644 --- a/lib/vagrant-libvirt/action/handle_box_image.rb +++ b/lib/vagrant-libvirt/action/handle_box_image.rb @@ -4,6 +4,10 @@ module VagrantPlugins module ProviderLibvirt module Action class HandleBoxImage + include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate + include VagrantPlugins::ProviderLibvirt::Util::StorageUtil + + @@lock = Mutex.new def initialize(app, _env) @@ -31,11 +35,12 @@ module VagrantPlugins config = env[:machine].provider_config box_image_file = env[:machine].box.directory.join('box.img').to_s env[:box_volume_name] = env[:machine].box.name.to_s.dup.gsub('/', '-VAGRANTSLASH-') - env[:box_volume_name] << "_vagrant_box_image_#{begin - env[:machine].box.version.to_s - rescue - '' - end}.img" + env[:box_volume_name] << "_vagrant_box_image_#{ + begin + env[:machine].box.version.to_s + rescue + '' + end}.img" # Override box_virtual_size if config.machine_virtual_size @@ -44,7 +49,7 @@ module VagrantPlugins # is not supported and will be ignored env[:ui].warn I18n.t( 'vagrant_libvirt.warnings.ignoring_virtual_size_too_small', - requested: config.machine_virtual_size, minimum: box_virtual_size + requested: config.machine_virtual_size, minimum: box_virtual_size ) else env[:ui].info I18n.t('vagrant_libvirt.manual_resize_required') @@ -75,17 +80,41 @@ module VagrantPlugins message = "Creating volume #{env[:box_volume_name]}" message << " in storage pool #{config.storage_pool_name}." @logger.info(message) - begin - fog_volume = env[:machine].provider.driver.connection.volumes.create( - name: env[:box_volume_name], - allocation: "#{box_image_size / 1024 / 1024}M", - capacity: "#{box_virtual_size}G", - format_type: box_format, - pool_name: config.storage_pool_name - ) - rescue Fog::Errors::Error => e - raise Errors::FogCreateVolumeError, - error_message: e.message + + if config.qemu_use_session + begin + @name = env[:box_volume_name] + @allocation = "#{box_image_size / 1024 / 1024}M" + @capacity = "#{box_virtual_size}G" + @format_type = box_format ? box_format : 'raw' + + @storage_volume_uid = storage_uid env + @storage_volume_gid = storage_gid env + + libvirt_client = env[:machine].provider.driver.connection.client + libvirt_pool = libvirt_client.lookup_storage_pool_by_name( + config.storage_pool_name + ) + libvirt_volume = libvirt_pool.create_volume_xml( + to_xml('default_storage_volume') + ) + rescue => e + raise Errors::CreatingVolumeError, + error_message: e.message + end + else + begin + fog_volume = env[:machine].provider.driver.connection.volumes.create( + name: env[:box_volume_name], + allocation: "#{box_image_size / 1024 / 1024}M", + capacity: "#{box_virtual_size}G", + format_type: box_format, + pool_name: config.storage_pool_name + ) + rescue Fog::Errors::Error => e + raise Errors::FogCreateVolumeError, + error_message: e.message + end end # Upload box image to storage pool @@ -103,7 +132,11 @@ module VagrantPlugins # storage pool. if env[:interrupted] || !ret begin - fog_volume.destroy + if config.qemu_use_session + libvirt_volume.delete + else + fog_volume.destroy + end rescue nil end @@ -113,6 +146,19 @@ module VagrantPlugins @app.call(env) end + def split_size_unit(text) + if text.kind_of? Integer + # if text is an integer, match will fail + size = text + unit = 'G' + else + matcher = text.match(/(\d+)(.+)/) + size = matcher[1] + unit = matcher[2] + end + [size, unit] + end + protected # Fog libvirt currently doesn't support uploading images to storage diff --git a/lib/vagrant-libvirt/action/handle_storage_pool.rb b/lib/vagrant-libvirt/action/handle_storage_pool.rb index 924f80d..04be07c 100644 --- a/lib/vagrant-libvirt/action/handle_storage_pool.rb +++ b/lib/vagrant-libvirt/action/handle_storage_pool.rb @@ -5,6 +5,8 @@ module VagrantPlugins module Action class HandleStoragePool include VagrantPlugins::ProviderLibvirt::Util::ErbTemplate + include VagrantPlugins::ProviderLibvirt::Util::StorageUtil + @@lock = Mutex.new @@ -37,6 +39,9 @@ module VagrantPlugins # Fog libvirt currently doesn't support creating pools. Use # ruby-libvirt client directly. begin + @storage_pool_path = storage_pool_path(env) + @storage_pool_uid = storage_uid(env) + @storage_pool_gid = storage_gid(env) libvirt_pool = env[:machine].provider.driver.connection.client.define_storage_pool_xml( to_xml('default_storage_pool') ) diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 0977ea4..113bf69 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -40,6 +40,7 @@ module VagrantPlugins # Libvirt storage pool name, where box image and instance snapshots will # be stored. attr_accessor :storage_pool_name + attr_accessor :storage_pool_path # Turn on to prevent hostname conflicts attr_accessor :random_hostname @@ -148,6 +149,9 @@ module VagrantPlugins # Additional qemuargs arguments attr_accessor :qemu_args + # Use qemu session instead of system + attr_accessor :qemu_use_session + def initialize @uri = UNSET_VALUE @driver = UNSET_VALUE @@ -251,6 +255,7 @@ module VagrantPlugins @mgmt_attach = UNSET_VALUE @qemu_args = [] + @qemu_use_session = UNSET_VALUE end def boot(device) @@ -542,7 +547,9 @@ module VagrantPlugins # Setup connection uri. uri = @driver.dup virt_path = case uri - when 'qemu', 'openvz', 'uml', 'phyp', 'parallels', 'kvm' + when 'qemu', 'kvm' + @qemu_use_session ? '/session' : '/system' + when 'openvz', 'uml', 'phyp', 'parallels' '/system' when '@en', 'esx' '/' @@ -592,6 +599,7 @@ module VagrantPlugins @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 + @storage_pool_path = nil if @storage_pool_path == UNSET_VALUE @random_hostname = false if @random_hostname == 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 @@ -706,6 +714,7 @@ module VagrantPlugins @mgmt_attach = true if @mgmt_attach == UNSET_VALUE @qemu_args = [] if @qemu_args == UNSET_VALUE + @qemu_use_session = false if @qemu_use_session == UNSET_VALUE end def validate(machine) diff --git a/lib/vagrant-libvirt/errors.rb b/lib/vagrant-libvirt/errors.rb index 506b973..52ca770 100644 --- a/lib/vagrant-libvirt/errors.rb +++ b/lib/vagrant-libvirt/errors.rb @@ -29,6 +29,10 @@ module VagrantPlugins error_key(:creating_storage_pool_error) end + class CreatingVolumeError < VagrantLibvirtError + error_key(:creating_volume_error) + end + class ImageUploadError < VagrantLibvirtError error_key(:image_upload_error) end diff --git a/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb b/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb index b63eea7..3e560ec 100644 --- a/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb +++ b/lib/vagrant-libvirt/templates/default_storage_pool.xml.erb @@ -3,11 +3,11 @@ - /var/lib/libvirt/images + <%= @storage_pool_path %> 0755 - -1 - -1 + <%= @storage_pool_uid %> + <%= @storage_pool_gid %> diff --git a/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb b/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb new file mode 100644 index 0000000..c4b2268 --- /dev/null +++ b/lib/vagrant-libvirt/templates/default_storage_volume.xml.erb @@ -0,0 +1,14 @@ + + <%= @name %> + <%= split_size_unit(@allocation)[0] %> + <%= split_size_unit(@capacity)[0] %> + + + + <%= @storage_volume_uid %> + <%= @storage_volume_gid %> + 0744 + + + + diff --git a/lib/vagrant-libvirt/util.rb b/lib/vagrant-libvirt/util.rb index f81c607..5efb3d9 100644 --- a/lib/vagrant-libvirt/util.rb +++ b/lib/vagrant-libvirt/util.rb @@ -5,6 +5,7 @@ module VagrantPlugins autoload :Collection, 'vagrant-libvirt/util/collection' autoload :Timer, 'vagrant-libvirt/util/timer' autoload :NetworkUtil, 'vagrant-libvirt/util/network_util' + autoload :StorageUtil, 'vagrant-libvirt/util/storage_util' autoload :ErrorCodes, 'vagrant-libvirt/util/error_codes' end end diff --git a/lib/vagrant-libvirt/util/storage_util.rb b/lib/vagrant-libvirt/util/storage_util.rb new file mode 100644 index 0000000..2b03547 --- /dev/null +++ b/lib/vagrant-libvirt/util/storage_util.rb @@ -0,0 +1,27 @@ + +module VagrantPlugins + module ProviderLibvirt + module Util + module StorageUtil + def storage_uid(env) + env[:machine].provider_config.qemu_use_session ? Process.uid : 0 + end + + def storage_gid(env) + env[:machine].provider_config.qemu_use_session ? Process.gid : 0 + end + + def storage_pool_path(env) + if env[:machine].provider_config.storage_pool_path + env[:machine].provider_config.storage_pool_path + elsif env[:machine].provider_config.qemu_use_session + File.expand_path('~/.local/share/libvirt/images') + else + '/var/lib/libvirt/images' + end + end + end + end + end +end + diff --git a/locales/en.yml b/locales/en.yml index cd88b56..207f881 100644 --- a/locales/en.yml +++ b/locales/en.yml @@ -107,6 +107,8 @@ en: `vagrant up` command again. creating_storage_pool_error: |- There was error while creating libvirt storage pool: %{error_message} + creating_volume_error: |- + There was error while creating libvirt volume: %{error_message} image_upload_error: |- Error while uploading image to storage pool: %{error_message} no_domain_error: |- From 7f50ca2a41bbaab573132ba00ec552f28a93c3cb Mon Sep 17 00:00:00 2001 From: qazokm Date: Fri, 23 Feb 2018 12:09:49 +0800 Subject: [PATCH 2/4] Add basic networking support for qemu session --- lib/vagrant-libvirt/action.rb | 4 +-- lib/vagrant-libvirt/action/wait_till_up.rb | 39 ++++++++++++++++------ lib/vagrant-libvirt/config.rb | 10 ++++++ lib/vagrant-libvirt/driver.rb | 29 ++++++++++++++++ lib/vagrant-libvirt/util/network_util.rb | 39 +++++++++++++++------- 5 files changed, 96 insertions(+), 25 deletions(-) diff --git a/lib/vagrant-libvirt/action.rb b/lib/vagrant-libvirt/action.rb index 682ef82..146d339 100644 --- a/lib/vagrant-libvirt/action.rb +++ b/lib/vagrant-libvirt/action.rb @@ -27,7 +27,7 @@ module VagrantPlugins if !env[:machine].config.vm.box b2.use CreateDomain b2.use CreateNetworks - #b2.use CreateNetworkInterfaces + b2.use CreateNetworkInterfaces b2.use SetBootOrder b2.use StartDomain else @@ -44,7 +44,7 @@ module VagrantPlugins b2.use PrepareNFSSettings b2.use ShareFolders b2.use CreateNetworks - #b2.use CreateNetworkInterfaces + b2.use CreateNetworkInterfaces b2.use SetBootOrder b2.use StartDomain diff --git a/lib/vagrant-libvirt/action/wait_till_up.rb b/lib/vagrant-libvirt/action/wait_till_up.rb index 3ee77ca..972f4e4 100644 --- a/lib/vagrant-libvirt/action/wait_till_up.rb +++ b/lib/vagrant-libvirt/action/wait_till_up.rb @@ -31,22 +31,39 @@ module VagrantPlugins # from arp table, either localy or remotely via ssh, if libvirt # connection was done via ssh. env[:ip_address] = nil - env[:metrics]['instance_ip_time'] = Util::Timer.time do - @logger.debug("Searching for IP for MAC address: #{domain.mac}") - env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip')) - retryable(on: Fog::Errors::TimeoutError, tries: 300) do - # If we're interrupted don't worry about waiting - return terminate(env) if env[:interrupted] + @logger.debug("Searching for IP for MAC address: #{domain.mac}") + env[:ui].info(I18n.t('vagrant_libvirt.waiting_for_ip')) - # Wait for domain to obtain an ip address - domain.wait_for(2) do - addresses.each_pair do |_type, ip| - env[:ip_address] = ip[0] unless ip[0].nil? + if env[:machine].provider_config.qemu_use_session + env[:metrics]['instance_ip_time'] = Util::Timer.time do + retryable(on: Fog::Errors::TimeoutError, tries: 300) do + # If we're interrupted don't worry about waiting + return terminate(env) if env[:interrupted] + + # Wait for domain to obtain an ip address + domain.wait_for(2) do + env[:ip_address] = env[:machine].provider.driver.get_ipaddress_system(domain.mac) + !env[:ip_address].nil? + end + end + end + else + env[:metrics]['instance_ip_time'] = Util::Timer.time do + retryable(on: Fog::Errors::TimeoutError, tries: 300) do + # If we're interrupted don't worry about waiting + return terminate(env) if env[:interrupted] + + # Wait for domain to obtain an ip address + domain.wait_for(2) do + addresses.each_pair do |_type, ip| + env[:ip_address] = ip[0] unless ip[0].nil? + end + !env[:ip_address].nil? end - !env[:ip_address].nil? end end end + @logger.info("Got IP address #{env[:ip_address]}") @logger.info("Time for getting IP: #{env[:metrics]['instance_ip_time']}") diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 113bf69..32ce9a5 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -46,6 +46,7 @@ module VagrantPlugins attr_accessor :random_hostname # Libvirt default network + attr_accessor :management_network_device attr_accessor :management_network_name attr_accessor :management_network_address attr_accessor :management_network_mode @@ -55,6 +56,9 @@ module VagrantPlugins attr_accessor :management_network_pci_bus attr_accessor :management_network_pci_slot + # System connection information + attr_accessor :system_uri + # Default host prefix (alternative to use project folder name) attr_accessor :default_prefix @@ -162,6 +166,7 @@ module VagrantPlugins @id_ssh_key_file = UNSET_VALUE @storage_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 @@ -171,6 +176,9 @@ module VagrantPlugins @management_network_pci_slot = UNSET_VALUE @management_network_pci_bus = UNSET_VALUE + # System connection information + @system_uri = UNSET_VALUE + # Domain specific settings. @uuid = UNSET_VALUE @memory = UNSET_VALUE @@ -601,6 +609,7 @@ module VagrantPlugins @storage_pool_name = 'default' if @storage_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 @@ -609,6 +618,7 @@ module VagrantPlugins @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 + @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE # generate a URI if none is supplied @uri = _generate_uri if @uri == UNSET_VALUE diff --git a/lib/vagrant-libvirt/driver.rb b/lib/vagrant-libvirt/driver.rb index c9482a0..8d64ac4 100644 --- a/lib/vagrant-libvirt/driver.rb +++ b/lib/vagrant-libvirt/driver.rb @@ -1,4 +1,5 @@ require 'fog/libvirt' +require 'libvirt' require 'log4r' module VagrantPlugins @@ -10,6 +11,7 @@ module VagrantPlugins # settings as a key to allow per machine connection attributes # to be used. @@connection = nil + @@system_connection = nil def initialize(machine) @logger = Log4r::Logger.new('vagrant_libvirt::driver') @@ -47,6 +49,17 @@ module VagrantPlugins @@connection end + def system_connection + # If already connected to libvirt, just use it and don't connect + # again. + return @@system_connection if @@system_connection + + config = @machine.provider_config + + @@system_connection = Libvirt::open_read_only(config.system_uri) + @@system_connection + end + def get_domain(mid) begin domain = connection.servers.get(mid) @@ -70,6 +83,9 @@ module VagrantPlugins def get_ipaddress(machine) # Find the machine domain = get_domain(machine.id) + if @machine.provider_config.qemu_use_session + return get_ipaddress_system domain.mac + end if domain.nil? # The machine can't be found @@ -99,6 +115,19 @@ module VagrantPlugins ip_address end + def get_ipaddress_system(mac) + ip_address = nil + + system_connection.list_all_networks.each do |net| + leases = net.dhcp_leases(mac, 0) + # Assume the lease expiring last is the current IP address + ip_address = leases.sort_by { |lse| lse["expirytime"] }.last["ipaddr"] if !leases.empty? + break if ip_address + end + + return ip_address + end + def state(machine) # may be other error states with initial retreival we can't handle begin diff --git a/lib/vagrant-libvirt/util/network_util.rb b/lib/vagrant-libvirt/util/network_util.rb index 1234da3..610bbbf 100644 --- a/lib/vagrant-libvirt/util/network_util.rb +++ b/lib/vagrant-libvirt/util/network_util.rb @@ -8,6 +8,8 @@ module VagrantPlugins include Vagrant::Util::NetworkIP def configured_networks(env, logger) + qemu_use_session = env[:machine].provider_config.qemu_use_session + management_network_device = env[:machine].provider_config.management_network_device management_network_name = env[:machine].provider_config.management_network_name management_network_address = env[:machine].provider_config.management_network_address management_network_mode = env[:machine].provider_config.management_network_mode @@ -33,18 +35,31 @@ module VagrantPlugins error_message: "#{management_network_address} does not include both an address and subnet mask" end - management_network_options = { - iface_type: :private_network, - network_name: management_network_name, - ip: Regexp.last_match(1), - netmask: Regexp.last_match(2), - dhcp_enabled: true, - forward_mode: management_network_mode, - guest_ipv6: management_network_guest_ipv6, - autostart: management_network_autostart, - bus: management_network_pci_bus, - slot: management_network_pci_slot - } + if qemu_use_session + management_network_options = { + iface_type: :public_network, + dev: management_network_device, + mode: 'bridge', + type: 'bridge', + bus: management_network_pci_bus, + slot: management_network_pci_slot + } + else + management_network_options = { + iface_type: :private_network, + network_name: management_network_name, + ip: Regexp.last_match(1), + netmask: Regexp.last_match(2), + dhcp_enabled: true, + forward_mode: management_network_mode, + guest_ipv6: management_network_guest_ipv6, + autostart: management_network_autostart, + bus: management_network_pci_bus, + slot: management_network_pci_slot + } + end + + unless management_network_mac.nil? management_network_options[:mac] = management_network_mac From 066e03f16ded599aef729b8bfc2bc3f2724ab41a Mon Sep 17 00:00:00 2001 From: Nicholas Date: Sun, 25 Feb 2018 12:43:07 +0800 Subject: [PATCH 3/4] Update README for QEMU Sesssion Support --- README.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0364193..9075191 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,7 @@ can help a lot :-) - [SSH Access To VM](#ssh-access-to-vm) - [Forwarded Ports](#forwarded-ports) - [Synced Folders](#synced-folders) +- [QEMU Session Support](#qemu-session-support) - [Customized Graphics](#customized-graphics) - [Box Format](#box-format) - [Create Box](#create-box) @@ -1084,7 +1085,7 @@ Name of network "foreman_managed" is key for define boot order ```ruby config.vm.define :pxeclient do |pxeclient| pxeclient.vm.network :private_network,ip: '10.0.0.5', - libvirt__network_name: "foreman_managed", + libvirt__network_name: "foreman_managed". libvirt__dhcp_enabled: false, libvirt__host_ip: '10.0.0.1' @@ -1163,6 +1164,34 @@ Further documentation on using 9p can be found in [kernel docs](https://www.kern **SECURITY NOTE:** for remote libvirt, nfs synced folders requires a bridged public network interface and you must connect to libvirt via ssh. +## QEMU Session Support + +vagrant-libvirt supports using the QEMU session connection to maintain Vagrant VMs. As the session connection does not have root access to the system features which require root will not work. Access to networks created by the system QEMU connection can be granted by using the [QEMU bridge helper](https://wiki.qemu.org/Features/HelperNetworking). The bridge helper is enabled by default on some distros but may need to be enabled/installed on others. + +An example configuration of a machine using the QEMU session connection: + +```ruby +Vagrant.configure("2") do |config| + config.vm.provider :libvirt do |libvirt| + # Use QEMU session instead of system connection + libvirt.qemu_use_session = true + # URI of QEMU session connection, default is as below + libvirt.uri = 'qemu:///session' + # URI of QEMU system connection, use to obtain IP address for management + libvirt.system_uri = 'qemu:///system' + # Path to store libvirt images for the virtual machine, default is as ~/.local/share/libvirt/images + libvirt.storage_pool_path = '/home/user/.local/share/libvirt/images' + # Management network device + libvirt.management_network_device = 'virbr0' + end + + # Public network configuration using existing network device + # Note: Private networks do not work with QEMU session enabled as root access is required to create new network devices + config.vm.network :public_network, :dev => "virbr1", + :mode => "bridge", + :type => "bridge" +end +``` ## Customized Graphics From 99371fee2b24e5f58793b7ce86824a47491d0372 Mon Sep 17 00:00:00 2001 From: dima Date: Sat, 17 Mar 2018 14:26:13 +0100 Subject: [PATCH 4/4] bug fixes for qemu_use_session --- lib/vagrant-libvirt/action/create_domain.rb | 16 +++++++++------- lib/vagrant-libvirt/config.rb | 5 +++-- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/vagrant-libvirt/action/create_domain.rb b/lib/vagrant-libvirt/action/create_domain.rb index f146c55..8077b67 100644 --- a/lib/vagrant-libvirt/action/create_domain.rb +++ b/lib/vagrant-libvirt/action/create_domain.rb @@ -129,13 +129,15 @@ module VagrantPlugins # If we have a box, take the path from the domain volume and set our storage_prefix. # If not, we dump the storage pool xml to get its defined path. # the default storage prefix is typically: /var/lib/libvirt/images/ - if env[:machine].config.vm.box - storage_prefix = File.dirname(@domain_volume_path) + '/' # steal - else - storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name) - raise Errors::NoStoragePool if storage_pool.nil? - xml = Nokogiri::XML(storage_pool.xml_desc) - storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/' + if !config.qemu_use_session + if env[:machine].config.vm.box + storage_prefix = File.dirname(@domain_volume_path) + '/' # steal + else + storage_pool = env[:machine].provider.driver.connection.client.lookup_storage_pool_by_name(@storage_pool_name) + raise Errors::NoStoragePool if storage_pool.nil? + xml = Nokogiri::XML(storage_pool.xml_desc) + storage_prefix = xml.xpath('/pool/target/path').inner_text.to_s + '/' + end end @disks.each do |disk| diff --git a/lib/vagrant-libvirt/config.rb b/lib/vagrant-libvirt/config.rb index 6c97e55..73d6e5d 100644 --- a/lib/vagrant-libvirt/config.rb +++ b/lib/vagrant-libvirt/config.rb @@ -347,7 +347,7 @@ module VagrantPlugins @cpu_topology[:sockets] = options[:sockets] @cpu_topology[:cores] = options[:cores] - @cpu_topology[:threads] = options[:threads] + @cpu_topology[:threads] = options[:threads] end def memorybacking(option, config = {}) @@ -622,6 +622,8 @@ module VagrantPlugins @management_network_pci_slot = nil if @management_network_pci_slot == UNSET_VALUE @system_uri = 'qemu:///system' if @system_uri == UNSET_VALUE + @qemu_use_session = false if @qemu_use_session == UNSET_VALUE + # generate a URI if none is supplied @uri = _generate_uri if @uri == UNSET_VALUE @@ -727,7 +729,6 @@ module VagrantPlugins @mgmt_attach = true if @mgmt_attach == UNSET_VALUE @qemu_args = [] if @qemu_args == UNSET_VALUE - @qemu_use_session = false if @qemu_use_session == UNSET_VALUE end def validate(machine)