Add basic networking support for qemu session

This commit is contained in:
qazokm
2018-02-23 12:09:49 +08:00
parent b0eddf6770
commit 7f50ca2a41
5 changed files with 96 additions and 25 deletions

View File

@@ -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

View File

@@ -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']}")

View File

@@ -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

View File

@@ -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

View File

@@ -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