diff --git a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb index debef85db0..d0967dcbfb 100644 --- a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb +++ b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb @@ -1792,12 +1792,34 @@ class VCenterVm vm = connection.find_vm_template(deploy_id) - spec_hash = calculate_addnic_spec(vm, mac, bridge, model) + spec_nics = calculate_addnic_spec(vm, mac, bridge, model) - spec = RbVmomi::VIM.VirtualMachineConfigSpec({:deviceChange => - [spec_hash]}) + spec_hash = {:deviceChange => [spec_nics]} + + + #B4897 track hot plugged nics + hotplugged_nics = vm.config.extraConfig.select do |val| + val[:key] == "opennebula.hotplugged_nics" + end + + if hotplugged_nics && !hotplugged_nics.empty? + hotplugged_nics = hotplugged_nics[0][:value].to_s + hotplugged_nics << mac.to_s << ";" if !hotplugged_nics.include?(mac) + else + hotplugged_nics = "" + hotplugged_nics << mac.to_s << ";" + end + + config_array = [{:key=>"opennebula.hotplugged_nics", + :value=>hotplugged_nics}] + extra_config_spec = {:extraConfig =>config_array} + + spec_hash.merge!(extra_config_spec) + + spec = RbVmomi::VIM.VirtualMachineConfigSpec(spec_hash) vm.ReconfigVM_Task(:spec => spec).wait_for_completion + end ############################################################################ @@ -1815,11 +1837,25 @@ class VCenterVm raise "Could not find NIC with mac address #{mac}" if nic.nil? + #B4897 track hot plugged nics + hotplugged_nics = vm.config.extraConfig.select do |val| + val[:key] == "opennebula.hotplugged_nics" + end + + config_array = [] + if hotplugged_nics && !hotplugged_nics.empty? + hotplugged_nics = hotplugged_nics[0][:value].to_s + hotplugged_nics.slice!(mac + ";") # remove hotplugged nic + config_array = [{:key=>"opennebula.hotplugged_nics", + :value=>hotplugged_nics}] + end + spec = { :deviceChange => [ :operation => :remove, :device => nic - ] + ], + :extraConfig => config_array } vm.ReconfigVM_Task(:spec => spec).wait_for_completion @@ -2635,19 +2671,32 @@ private :value=>context_text}] end - if config_array != [] - context_vnc_spec = {:extraConfig =>config_array} - end - device_change = [] # NIC section, build the reconfig hash nics = xml.root.get_elements("/VM/TEMPLATE/NIC") - nic_spec = {} # If the VM is not new, avoid readding NiCs if !newvm + nic_array = [] + + # Get MACs from NICs inside VM template + one_mac_addresses = Array.new + nics.each{|nic| + one_mac_addresses << nic.elements["MAC"].text + } + + # B4897 - Get mac of NICs that were hot-plugged from vCenter extraConfig + hotplugged_nics = [] + extraconfig_nics = vm.config.extraConfig.select do |val| + val[:key] == "opennebula.hotplugged_nics" + end + + if extraconfig_nics && !extraconfig_nics.empty? + hotplugged_nics = extraconfig_nics[0][:value].to_s.split(";") + end + vm.config.hardware.device.each{ |dv| if is_nic?(dv) nics.each{|nic| @@ -2655,8 +2704,20 @@ private nics.delete(nic) end } + + # B4897 - Remove detached NICs from vCenter that were unplugged in POWEROFF + if !one_mac_addresses.include?(dv.macAddress) && hotplugged_nics.include?(dv.macAddress) + nic_array << { :operation => :remove, :device => dv} + hotplugged_nics.delete(dv.macAddress) + config_array << { + :key => 'opennebula.hotplugged_nics', + :value => hotplugged_nics.join(";") + } + end end } + + device_change += nic_array end if !nics.nil? @@ -2730,6 +2791,10 @@ private :memoryMB => memory } # Perform the VM reconfiguration + if config_array != [] + context_vnc_spec = {:extraConfig =>config_array} + end + spec_hash = context_vnc_spec.merge(capacity_spec) if device_change.length > 0 spec_hash.merge!({ :deviceChange => device_change })