Merge pull request #129 from sciurus/116_and_128

Fixes for 116 and 128
This commit is contained in:
Dmitry Vasilets 2014-01-20 14:01:04 -08:00
commit 8fefca0f64
3 changed files with 49 additions and 25 deletions

View File

@ -99,8 +99,6 @@ This provider exposes quite a few provider-specific configuration options:
* `password` - Password to access Libvirt. * `password` - Password to access Libvirt.
* `id_ssh_key_file` - The id ssh key file name to access Libvirt (eg: id_dsa or id_rsa or ... in the user .ssh directory) * `id_ssh_key_file` - The id ssh key file name to access Libvirt (eg: id_dsa or id_rsa or ... in the user .ssh directory)
* `storage_pool_name` - Libvirt storage pool name, where box image and instance snapshots will be stored. * `storage_pool_name` - Libvirt storage pool name, where box image and instance snapshots will be stored.
* `management_network_name` - Name of libvirt network to which all VMs will be connected. If not specified the default is 'vagrant-libvirt'.
* `management_network_address` - Address of network to which all VMs will be connected. Must include the address and subnet mask. If not specified the default is '192.168.121.0/24'.
### Domain Specific Options ### Domain Specific Options
@ -236,15 +234,24 @@ starts with 'libvirt__' string. Here is a list of those options:
Default mode is 'bridge'. Default mode is 'bridge'.
* `:mac` - MAC address for the interface. * `:mac` - MAC address for the interface.
## Obtaining Domain IP Address ### Management Network
Libvirt doesn't provide standard way how to find out an IP address of running Vagrant-libvirt uses a private network to perform some management operations
domain. But we know, what is MAC address of virtual machine. Libvirt is closely on VMs. All VMs will have an interface connected to this network and
connected with dnsmasq server, which acts also as a DHCP server. Dnsmasq server an IP address dynamically assigned by libvirt. This is in addition to any
makes lease information public in `/var/lib/libvirt/dnsmasq` directory, or in networks you configure. The name and address used by this network are
`/var/lib/misc/dnsmasq.leases` file on some systems. This is the place, where configurable at the provider level.
information like which MAC address has which IP address resides and it's parsed
by vagrant-libvirt plugin. * `management_network_name` - Name of libvirt network to which all VMs will be connected. If not specified the default is 'vagrant-libvirt'.
* `management_network_address` - Address of network to which all VMs will be connected. Must include the address and subnet mask. If not specified the default is '192.168.121.0/24'.
You may wonder how vagrant-libvirt knows the IP address a VM received.
Libvirt doesn't provide a standard way to find out the IP address of a running
domain. But we do know the MAC address of the virtual machine's interface on
the management network. Libvirt is closely connected with dnsmasq, which acts as
a DHCP server. dnsmasq writes lease information in the `/var/lib/libvirt/dnsmasq`
directory. Vagrant-libvirt looks for the MAC address in this file and extracts
the corresponding IP address.
## SSH Access To VM ## SSH Access To VM

View File

@ -57,14 +57,18 @@ module VagrantPlugins
next if env[:result] next if env[:result]
b2.use Call, IsSuspended do |env2, b3| b2.use Call, IsSuspended do |env2, b3|
# if vm is suspended resume it then exit
if env2[:result] if env2[:result]
b3.use ResumeDomain b3.use ResumeDomain
next next
end end
# VM is not running or suspended. Start it.. Machine should gain # VM is not running or suspended.
# IP address when comming up, so wait for dhcp lease and store IP
# into machines data_dir. # Ensure networks are created and active
b3.use CreateNetworks
# Handle shared folders
if Vagrant::VERSION < "1.4.0" if Vagrant::VERSION < "1.4.0"
b3.use NFS b3.use NFS
else else
@ -74,7 +78,11 @@ module VagrantPlugins
b3.use PrepareNFSSettings b3.use PrepareNFSSettings
b3.use ShareFolders b3.use ShareFolders
# Start it..
b3.use StartDomain b3.use StartDomain
# Machine should gain IP address when comming up,
# so wait for dhcp lease and store IP into machines data_dir.
b3.use WaitTillUp b3.use WaitTillUp
end end
end end

View File

@ -18,7 +18,7 @@ module VagrantPlugins
# data directory, created_networks file holds UUIDs of each network. # data directory, created_networks file holds UUIDs of each network.
created_networks_file = env[:machine].data_dir + 'created_networks' created_networks_file = env[:machine].data_dir + 'created_networks'
@logger.info 'Attepmt destroy network' @logger.info 'Checking if any networks were created'
# If created_networks file doesn't exist, there are no networks we # If created_networks file doesn't exist, there are no networks we
# need to remove. # need to remove.
unless File.exist?(created_networks_file) unless File.exist?(created_networks_file)
@ -26,39 +26,45 @@ module VagrantPlugins
return @app.call(env) return @app.call(env)
end end
@logger.info 'file with network exists' @logger.info 'File with created networks exists'
# Iterate over each created network UUID and try to remove it. # Iterate over each created network UUID and try to remove it.
created_networks = [] created_networks = []
file = File.open(created_networks_file, 'r') file = File.open(created_networks_file, 'r')
file.readlines.each do |network_uuid| file.readlines.each do |network_uuid|
@logger.info network_uuid @logger.info "Checking for #{network_uuid}"
# lookup_network_by_uuid throws same exception
# if there is an error or if the network just doesn't exist
begin begin
libvirt_network = env[:libvirt_compute].client.lookup_network_by_uuid( libvirt_network = env[:libvirt_compute].client.lookup_network_by_uuid(
network_uuid) network_uuid)
rescue rescue Libvirt::RetrieveError => e
raise network_uuid # this network is already destroyed, so move on
next if e.message =~ /Network not found/
@logger.info "It is already undefined"
next
# some other error occured, so raise it again
else
raise e
end
end end
# Maybe network doesn't exist anymore.
next unless libvirt_network
# Skip removing if network has still active connections. # Skip removing if network has still active connections.
xml = Nokogiri::XML(libvirt_network.xml_desc) xml = Nokogiri::XML(libvirt_network.xml_desc)
connections = xml.xpath('/network/@connections').first connections = xml.xpath('/network/@connections').first
@logger.info connections
if connections != nil if connections != nil
@logger.info "Still has connections so will not undefine"
created_networks << network_uuid created_networks << network_uuid
next next
end end
# Shutdown network first.
libvirt_network.destroy
# Shutdown network first.
# Undefine network. # Undefine network.
begin begin
libvirt_network.destroy
libvirt_network.undefine libvirt_network.undefine
@logger.info "Undefined it"
rescue => e rescue => e
raise Error::DestroyNetworkError, raise Error::DestroyNetworkError,
network_name: libvirt_network.name, network_name: libvirt_network.name,
@ -68,13 +74,16 @@ module VagrantPlugins
file.close file.close
# Update status of created networks after removing some/all of them. # Update status of created networks after removing some/all of them.
# Not sure why we are doing this, something else seems to always delete the file
if created_networks.length > 0 if created_networks.length > 0
File.open(created_networks_file, 'w') do |file| File.open(created_networks_file, 'w') do |file|
@logger.info "Writing new created_networks file"
created_networks.each do |network_uuid| created_networks.each do |network_uuid|
file.puts network_uuid file.puts network_uuid
end end
end end
else else
@logger.info "Deleting created_networks file"
File.delete(created_networks_file) File.delete(created_networks_file)
end end