1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-01-11 05:17:41 +03:00

Feature #i3307: Add attach/detach nic for vCenter VMs

This commit is contained in:
Tino Vazquez 2014-11-25 19:23:39 +01:00 committed by Ruben S. Montero
parent 1c72903cc5
commit 547bc6c8a5
8 changed files with 223 additions and 13 deletions

View File

@ -1219,7 +1219,8 @@ VMM_EXEC_ETC_FILES="src/vmm_mad/exec/vmm_execrc \
src/vmm_mad/exec/vmm_exec_kvm.conf \
src/vmm_mad/exec/vmm_exec_xen3.conf \
src/vmm_mad/exec/vmm_exec_xen4.conf \
src/vmm_mad/exec/vmm_exec_vmware.conf"
src/vmm_mad/exec/vmm_exec_vmware.conf \
src/vmm_mad/exec/vmm_exec_vcenter.conf"
#-------------------------------------------------------------------------------
# Hook Manager driver config. files, to be installed under $ETC_LOCATION/hm

View File

@ -465,6 +465,7 @@ VM_MAD = [
# name = "vcenter",
# executable = "one_vmm_sh",
# arguments = "-p -t 15 -r 0 vcenter -s sh",
# default = "vmm_exec/vmm_exec_vcenter.conf",
# type = "xml" ]
#-------------------------------------------------------------------------------

View File

@ -15,7 +15,7 @@ enabled_tabs:
clusters-tab: true
hosts-tab: true
datastores-tab: false
vnets-tab: false
vnets-tab: true
secgroups-tab: false
marketplace-tab: false
oneflow-dashboard: true
@ -169,8 +169,8 @@ tabs:
VM.attachdisk: true
VM.detachdisk: true
VM.saveas: false
VM.attachnic: false
VM.detachnic: false
VM.attachnic: true
VM.detachnic: true
VM.snapshot_create: true
VM.snapshot_revert: true
VM.snapshot_delete: true

View File

@ -2461,6 +2461,10 @@ function setup_disk_tab_content(disk_section, str_disk_tab_id) {
size_input.val(10);
update_final_size_input();
if (Config.isTemplateCreationTabEnabled('network')){
str += "<dd class='hypervisor only_kvm only_vmware only_xen only_vcenter'><a href='#networkTab'><i class='fa fa-globe'></i><br>"+tr("Network")+"</a></dd>";
}
// init::start is ignored for some reason
size_slider.val(1000);

View File

@ -0,0 +1,23 @@
# ---------------------------------------------------------------------------- #
# Copyright 2010-2014, C12G Labs S.L #
# #
# Licensed under the Apache License, Version 2.0 (the "License"); you may #
# not use this file except in compliance with the License. You may obtain #
# a copy of the License at #
# #
# http://www.apache.org/licenses/LICENSE-2.0 #
# #
# Unless required by applicable law or agreed to in writing, software #
# distributed under the License is distributed on an "AS IS" BASIS, #
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
# See the License for the specific language governing permissions and #
# limitations under the License. #
# ---------------------------------------------------------------------------- #
# Default configuration attributes for the vCenter driver
# (all domains will use these values as defaults)
# Valid atributes:
# - nic[model]
NIC=[MODEL="VirtualE1000"]

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
@ -16,5 +16,33 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
mac = ARGV[1]
bridge = ARGV[2]
model = ARGV[3]
host = ARGV[6]
begin
VCenterDriver::VCenterVm.attach_nic(deploy_id,
mac,
bridge,
model,
host)
rescue Exception => e
STDERR.puts "Attach NIC for VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
@ -16,5 +16,30 @@
# limitations under the License. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
ONE_LOCATION=ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby" if !defined?(RUBY_LIB_LOCATION)
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << File.dirname(__FILE__)
require 'vcenter_driver'
deploy_id = ARGV[0]
mac = ARGV[1]
host = ARGV[3]
begin
VCenterDriver::VCenterVm.detach_nic(deploy_id,
mac,
host)
rescue Exception => e
STDERR.puts "Detach NIC for VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end

View File

@ -663,6 +663,54 @@ class VCenterVm
snapshot.RevertToSnapshot_Task(revert_snapshot_hash).wait_for_completion
end
############################################################################
# Attach NIC to a VM
# @param deploy_id vcenter identifier of the VM
# @param mac MAC address of the NIC to be attached
# @param bridge name of the Network in vCenter
# @param model model of the NIC to be attached
# @param host hostname of the ESX where the VM is running
############################################################################
def self.attach_nic(deploy_id, mac, bridge, model, host)
hid = VIClient::translate_hostname(host)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
spec_hash = calculate_addnic_spec(vm, mac, bridge, model)
spec = RbVmomi::VIM.VirtualMachineConfigSpec({:deviceChange =>
[spec_hash]})
vm.ReconfigVM_Task(:spec => spec).wait_for_completion
end
############################################################################
# Detach NIC from a VM
############################################################################
def self.detach_nic(deploy_id, mac, host)
hid = VIClient::translate_hostname(host)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
nic = vm.config.hardware.device.find { |d|
(d.class.ancestors[1] == RbVmomi::VIM::VirtualEthernetCard) &&
(d.macAddress == mac)
}
raise "Could not find NIC with mac address #{mac}" if nic.nil?
spec = {
:deviceChange => [
:operation => :remove,
:device => nic
]
}
vm.ReconfigVM_Task(:spec => spec).wait_for_completion
end
########################################################################
# Initialize the vm monitor information
########################################################################
@ -768,6 +816,65 @@ private
end
end
########################################################################
# Returns the spec to reconfig a VM and add a NIC
########################################################################
def self.calculate_addnic_spec(vm, mac, bridge, model)
network = vm.runtime.host.network.select{|n| n.name==bridge}
if network.empty?
raise "Network #{bridge} not found in host #{vm.runtime.host.name}"
else
network = network[0]
end
card_num = 1 # start in one, we want the next avaliable id
vm.config.hardware.device.each{ |dv|
if dv.class.ancestors[1] == RbVmomi::VIM::VirtualEthernetCard
card_num = card_num + 1
end
}
model = model.nil? ? nil : model.downcase
nic_card = case model
when "virtuale1000"
RbVmomi::VIM::VirtualE1000
when "virtuale1000e"
RbVmomi::VIM::VirtualE1000e
when "virtualpcnet32"
RbVmomi::VIM::VirtualPCNet32
when "virtualsriovethernetcard"
RbVmomi::VIM::VirtualSriovEthernetCard
when "virtualvmxnetm"
RbVmomi::VIM::VirtualVmxnetm
when "virtualvmxnet2"
RbVmomi::VIM::VirtualVmxnet2
when "virtualvmxnet3"
RbVmomi::VIM::VirtualVmxnet3
else # If none matches, use VirtualE1000
RbVmomi::VIM::VirtualE1000
end
backing = RbVmomi::VIM.VirtualEthernetCardNetworkBackingInfo(
:deviceName => bridge,
:network => network)
return {:operation => :add,
:device => nic_card.new(
:key => 0,
:deviceInfo => {
:label => "net" + card_num.to_s,
:summary => bridge
},
:backing => backing,
:addressType => mac ? 'manual' : 'generated',
:macAddress => mac
)
}
end
########################################################################
# Clone a vCenter VM Template and leaves it powered on
########################################################################
@ -784,7 +891,7 @@ private
!type.nil? && type.text.downcase == "vcenter"
}
raise "Cannot find VCenter element in VM template." if template.nil?
raise "Cannot find vCenter element in VM template." if template.nil?
uuid = template.elements["VM_TEMPLATE"]
@ -829,7 +936,8 @@ private
vnc_listen = vnc_listen.text
end
config_array = []
config_array = []
context_vnc_spec = {}
if vnc_port
config_array +=
@ -852,7 +960,27 @@ private
end
if config_array != []
spec_hash = {:extraConfig =>config_array}
context_vnc_spec = {:extraConfig =>config_array}
end
# Take care of the NIC section, build the reconfig hash
nics = xml.root.get_elements("//TEMPLATE/NIC")
nic_spec = {}
if !nics.nil?
nic_array = []
nics.each{|nic|
mac = nic.elements["MAC"].text
bridge = nic.elements["BRIDGE"].text
model = nic.elements["MODEL"] ? nic.elements["MODEL"].text : nil
nic_array << calculate_addnic_spec(vm, mac, bridge, model)
}
nic_spec = {:deviceChange => nic_array}
end
if !context_vnc_spec.empty? or !nic_spec.empty?
spec_hash = context_vnc_spec.merge(nic_spec)
spec = RbVmomi::VIM.VirtualMachineConfigSpec(spec_hash)
vm.ReconfigVM_Task(:spec => spec).wait_for_completion
end