lib/vagrant-vminfo/plugin.rb in vagrant-vminfo-0.0.1 vs lib/vagrant-vminfo/plugin.rb in vagrant-vminfo-0.0.2
- old
+ new
@@ -26,46 +26,119 @@
end
class InfoCommand < Vagrant.plugin(2, :command)
include VagrantPlugins::CommandUp::StartMixins
+ def get_vm_info(vm)
+ # Get some provider specific details for vm
+ provider = vm.provider_name.id2name
+ if provider == 'virtualbox'
+ return get_vm_info_virtualbox(vm)
+ elsif provider == 'vmware_workstation'
+ return get_vm_info_vmware_workstation(vm)
+ end
+ end
+
+ def get_vm_info_virtualbox(vm)
+ # Get VM info by virtualbox provider
+ # All we need is network interfaces details
+
+ networks = []
+ begin
+ nic_count = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/Count")[/Value: (\d)/, 1]
+ rescue Exception => e
+ @logger.warn(e.message)
+ nic_count = 0
+ else
+ nic_count = Integer(nic_count)
+ end
+ # Check nic_count is not defined in case of VBox Guest Additions not install, or some other issue
+ if nic_count > 0
+ (0..(nic_count-1)).each do |i|
+ nic_ip = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/V4/IP")[/Value: (.*)/, 1]
+ nic_mac = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/MAC")[/Value: (.*)/, 1]
+ nic_broadcast = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/V4/Broadcast")[/Value: (.*)/, 1]
+ nic_netmask = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/V4/Netmask")[/Value: (.*)/, 1]
+ # Get the number of this network device based on the mac address
+ # TODO: probably just should just get a hash of all of this info somehow, my ruby foo is weak
+ nic_number = vm.provider.driver.execute("showvminfo", vm.id, "--machinereadable")[/\w*(\d)=\"#{nic_mac}\"/, 1]
+ nic_type = vm.provider.driver.execute("showvminfo", vm.id, "--machinereadable")[/nic#{nic_number}=\"(.*)\"/, 1]
+ networks << {'ip' => nic_ip,
+ 'mac' => nic_mac,
+ 'netmask' => nic_netmask,
+ 'broadcast' => nic_broadcast,
+ 'type' => nic_type}
+ end
+ end
+ return {"networks" => networks}
+ end
+
+ def get_vm_info_vmware_workstation(vm)
+ # Get VM info by virtualbox provider
+ # We can get some network interfaces details and current IP address
+
+ # Collect details for all the network interfaces
+ nics = {}
+ vm.provider.driver.send(:read_vmx_data).each do |key, val|
+ key1, key2 = key.split('.')
+ m = /^ethernet\d+$/.match(key1)
+ if m
+ if !nics.include?(m[0])
+ nics[m[0]] = {}
+ end
+ nics[m[0]][key2] = val
+ end
+ end
+
+ # Check and normalize collected network information
+ networks = []
+ nics.values.each do |nic|
+ nic_type = nic['connectiontype']
+ nic_addresstype = nic['addresstype']
+ nic_mac = nic_addresstype == 'generated' ? nic['generatedaddress'] : nic['address']
+ #TODO: For now I don't know simple way to retrieve these details
+ #nic_ip = nil
+ #nic_netmask = nil
+ #nic_broadcast = nil
+
+ networks << {#'ip' => nic_ip,
+ 'mac' => nic_mac,
+ #'netmask' => nic_netmask,
+ #'broadcast' => nic_broadcast,
+ 'type' => nic_type}
+ end
+
+ # We can try to get IP address for VM but can not assign it to any network interface
+ ip = nil
+ begin
+ resp = vm.provider.driver.send(:vmrun, *['getGuestIPAddress', vm.id])
+ rescue Exception => e
+ @logger.warn(e.message)
+ else
+ m = /(?<ip>\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3})/.match(resp.stdout)
+ ip = (resp.exit_code == 0 and m) ? m['ip'] : nil
+ end
+
+ return {'ip' => ip,
+ 'networks' => networks }
+ end
+
def execute
# Not sure if this is the only way to do this? How else would I get argv?
argv = parse_options(OptionParser.new)
info = {}
with_target_vms(argv) do |vm|
info["name"] = vm.name.id2name
- info["id"] = vm.id
- info["provider"] = vm.provider_name.id2name
- info["networks"] = []
-
- @nic_count = Integer(vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/Count")[/Value: (\d)/, 1])
- (0..(@nic_count-1)).each do |i|
- nic = {}
-
- @nic_ip = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/V4/IP")[/Value: (.*)/, 1]
- @nic_mac = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/MAC")[/Value: (.*)/, 1]
- @nic_broadcast = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/V4/Broadcast")[/Value: (.*)/, 1]
- @nic_netmask = vm.provider.driver.execute("guestproperty", "get", vm.id, "/VirtualBox/GuestInfo/Net/#{i}/V4/Netmask")[/Value: (.*)/, 1]
-
- # Get the number of this network device based on the mac address
- # TODO: probably just should just get a hash of all of this info somehow, my ruby foo is weak
- @nic_number = vm.provider.driver.execute("showvminfo", vm.id, "--machinereadable")[/\w*(\d)=\"#{@nic_mac}\"/, 1]
- @nic_type = vm.provider.driver.execute("showvminfo", vm.id, "--machinereadable")[/nic#{@nic_number}=\"(.*)\"/, 1]
-
- nic['ip'] = @nic_ip
- nic['mac'] = @nic_mac
- nic['netmask'] = @nic_netmask
- nic['broadcast'] = @nic_broadcast
- nic['type'] = @nic_type
-
- # Append to the networks array
- info["networks"] << nic
+ info["status"] = vm.state.id.id2name
+ # Check if vm is running - try to get some provider specific details
+ if vm.state.id == :running
+ info["id"] = vm.id
+ info["provider"] = vm.provider_name.id2name
+ info.merge!(get_vm_info(vm))
end
end
-
puts info.to_yaml
end
end
end