diff --git a/install.sh b/install.sh
index 513aac3942..31ab759be7 100755
--- a/install.sh
+++ b/install.sh
@@ -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
diff --git a/share/etc/oned.conf b/share/etc/oned.conf
index e2daaf1463..e704859096 100644
--- a/share/etc/oned.conf
+++ b/share/etc/oned.conf
@@ -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" ]
#-------------------------------------------------------------------------------
diff --git a/src/sunstone/etc/sunstone-views/vcenter.yaml b/src/sunstone/etc/sunstone-views/vcenter.yaml
index ac09050815..70b8446020 100644
--- a/src/sunstone/etc/sunstone-views/vcenter.yaml
+++ b/src/sunstone/etc/sunstone-views/vcenter.yaml
@@ -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
diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js
index ee467ada80..965c50b764 100644
--- a/src/sunstone/public/js/plugins/templates-tab.js
+++ b/src/sunstone/public/js/plugins/templates-tab.js
@@ -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 += "
"+tr("Network")+"";
+ }
+
// init::start is ignored for some reason
size_slider.val(1000);
diff --git a/src/vmm_mad/exec/vmm_exec_vcenter.conf b/src/vmm_mad/exec/vmm_exec_vcenter.conf
new file mode 100644
index 0000000000..0349eb248d
--- /dev/null
+++ b/src/vmm_mad/exec/vmm_exec_vcenter.conf
@@ -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"]
+
diff --git a/src/vmm_mad/remotes/vcenter/attach_nic b/src/vmm_mad/remotes/vcenter/attach_nic
index 8aeaf8eba5..88d6d1ebf8 100755
--- a/src/vmm_mad/remotes/vcenter/attach_nic
+++ b/src/vmm_mad/remotes/vcenter/attach_nic
@@ -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
diff --git a/src/vmm_mad/remotes/vcenter/detach_nic b/src/vmm_mad/remotes/vcenter/detach_nic
index 8aeaf8eba5..55b06cbcd5 100755
--- a/src/vmm_mad/remotes/vcenter/detach_nic
+++ b/src/vmm_mad/remotes/vcenter/detach_nic
@@ -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
\ No newline at end of file
diff --git a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb
index 43708328a0..8abde72f21 100644
--- a/src/vmm_mad/remotes/vcenter/vcenter_driver.rb
+++ b/src/vmm_mad/remotes/vcenter/vcenter_driver.rb
@@ -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