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.
* `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.
* `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
@ -236,15 +234,24 @@ starts with 'libvirt__' string. Here is a list of those options:
Default mode is 'bridge'.
* `: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
domain. But we know, what is MAC address of virtual machine. Libvirt is closely
connected with dnsmasq server, which acts also as a DHCP server. Dnsmasq server
makes lease information public in `/var/lib/libvirt/dnsmasq` directory, or in
`/var/lib/misc/dnsmasq.leases` file on some systems. This is the place, where
information like which MAC address has which IP address resides and it's parsed
by vagrant-libvirt plugin.
Vagrant-libvirt uses a private network to perform some management operations
on VMs. All VMs will have an interface connected to this network and
an IP address dynamically assigned by libvirt. This is in addition to any
networks you configure. The name and address used by this network are
configurable at the provider level.
* `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

View File

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

View File

@ -18,7 +18,7 @@ module VagrantPlugins
# data directory, created_networks file holds UUIDs of each network.
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
# need to remove.
unless File.exist?(created_networks_file)
@ -26,39 +26,45 @@ module VagrantPlugins
return @app.call(env)
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.
created_networks = []
file = File.open(created_networks_file, 'r')
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
libvirt_network = env[:libvirt_compute].client.lookup_network_by_uuid(
network_uuid)
rescue
raise network_uuid
next
rescue Libvirt::RetrieveError => e
# this network is already destroyed, so move on
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
# Maybe network doesn't exist anymore.
next unless libvirt_network
# Skip removing if network has still active connections.
xml = Nokogiri::XML(libvirt_network.xml_desc)
connections = xml.xpath('/network/@connections').first
@logger.info connections
if connections != nil
@logger.info "Still has connections so will not undefine"
created_networks << network_uuid
next
end
# Shutdown network first.
libvirt_network.destroy
# Shutdown network first.
# Undefine network.
begin
libvirt_network.destroy
libvirt_network.undefine
@logger.info "Undefined it"
rescue => e
raise Error::DestroyNetworkError,
network_name: libvirt_network.name,
@ -68,13 +74,16 @@ module VagrantPlugins
file.close
# 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
File.open(created_networks_file, 'w') do |file|
@logger.info "Writing new created_networks file"
created_networks.each do |network_uuid|
file.puts network_uuid
end
end
else
@logger.info "Deleting created_networks file"
File.delete(created_networks_file)
end