Merge branch 'feature-2911b'

This commit is contained in:
Ruben S. Montero committed 2014-09-29 20:03:48 +02:00
commit c41ec419dd
31 files changed
+2283 -65

No files matched your search

+31 -1
View File
@@ -247,6 +247,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/im/xen3-probes.d \
$VAR_LOCATION/remotes/im/xen4-probes.d \
$VAR_LOCATION/remotes/im/vmware.d \
$VAR_LOCATION/remotes/im/vcenter.d \
$VAR_LOCATION/remotes/im/ec2.d \
$VAR_LOCATION/remotes/im/sl.d \
$VAR_LOCATION/remotes/im/az.d \
@@ -255,6 +256,7 @@ VAR_DIRS="$VAR_LOCATION/remotes \
$VAR_LOCATION/remotes/vmm/xen3 \
$VAR_LOCATION/remotes/vmm/xen4 \
$VAR_LOCATION/remotes/vmm/vmware \
$VAR_LOCATION/remotes/vmm/vcenter \
$VAR_LOCATION/remotes/vmm/ec2 \
$VAR_LOCATION/remotes/vmm/sl \
$VAR_LOCATION/remotes/vmm/az \
@@ -407,6 +409,7 @@ INSTALL_FILES=(
IM_PROBES_XEN4_FILES:$VAR_LOCATION/remotes/im/xen4.d
IM_PROBES_XEN4_PROBES_FILES:$VAR_LOCATION/remotes/im/xen4-probes.d
IM_PROBES_VMWARE_FILES:$VAR_LOCATION/remotes/im/vmware.d
IM_PROBES_VCENTER_FILES:$VAR_LOCATION/remotes/im/vcenter.d
IM_PROBES_EC2_FILES:$VAR_LOCATION/remotes/im/ec2.d
IM_PROBES_SL_FILES:$VAR_LOCATION/remotes/im/sl.d
IM_PROBES_AZ_FILES:$VAR_LOCATION/remotes/im/az.d
@@ -422,6 +425,7 @@ INSTALL_FILES=(
VMM_EXEC_XEN3_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen3
VMM_EXEC_XEN4_SCRIPTS:$VAR_LOCATION/remotes/vmm/xen4
VMM_EXEC_VMWARE_SCRIPTS:$VAR_LOCATION/remotes/vmm/vmware
VMM_EXEC_VCENTER_SCRIPTS:$VAR_LOCATION/remotes/vmm/vcenter
VMM_EXEC_EC2_SCRIPTS:$VAR_LOCATION/remotes/vmm/ec2
VMM_EXEC_SL_SCRIPTS:$VAR_LOCATION/remotes/vmm/sl
VMM_EXEC_AZ_SCRIPTS:$VAR_LOCATION/remotes/vmm/az
@@ -599,6 +603,7 @@ BIN_FILES="src/nebula/oned \
src/cli/onezone \
src/cli/oneflow \
src/cli/oneflow-template \
src/cli/onevcenter \
src/onedb/onedb \
src/mad/utils/tty_expect \
share/scripts/one"
@@ -759,6 +764,28 @@ VMM_EXEC_VMWARE_SCRIPTS="src/vmm_mad/remotes/vmware/cancel \
src/vmm_mad/remotes/vmware/vmware_driver.rb \
src/vmm_mad/remotes/vmware/vi_driver.rb"
#-------------------------------------------------------------------------------
# VMM Driver vCenter scripts, installed under $REMOTES_LOCATION/vmm/vcenter
#-------------------------------------------------------------------------------
VMM_EXEC_VCENTER_SCRIPTS="src/vmm_mad/remotes/vcenter/cancel \
src/vmm_mad/remotes/vcenter/attach_disk \
src/vmm_mad/remotes/vcenter/detach_disk \
src/vmm_mad/remotes/vcenter/attach_nic \
src/vmm_mad/remotes/vcenter/detach_nic \
src/vmm_mad/remotes/vcenter/snapshot_create \
src/vmm_mad/remotes/vcenter/snapshot_revert \
src/vmm_mad/remotes/vcenter/snapshot_delete \
src/vmm_mad/remotes/vcenter/deploy \
src/vmm_mad/remotes/vcenter/migrate \
src/vmm_mad/remotes/vcenter/restore \
src/vmm_mad/remotes/vcenter/reboot \
src/vmm_mad/remotes/vcenter/reset \
src/vmm_mad/remotes/vcenter/save \
src/vmm_mad/remotes/vcenter/poll \
src/vmm_mad/remotes/vcenter/shutdown \
src/vmm_mad/remotes/vcenter/vcenter_driver.rb"
#------------------------------------------------------------------------------
# VMM Driver EC2 scripts, to be installed under $REMOTES_LOCATION/vmm/ec2
#------------------------------------------------------------------------------
@@ -870,6 +897,8 @@ IM_PROBES_XEN4_PROBES_FILES="src/im_mad/remotes/xen-probes.d/xen.rb \
IM_PROBES_VMWARE_FILES="src/im_mad/remotes/vmware.d/vmware.rb"
IM_PROBES_VCENTER_FILES="src/im_mad/remotes/vcenter.d/vcenter.rb"
IM_PROBES_EC2_FILES="src/im_mad/remotes/ec2.d/poll"
IM_PROBES_SL_FILES="src/im_mad/remotes/sl.d/poll"
@@ -1517,7 +1546,8 @@ SUNSTONE_PUBLIC_JS_PLUGINS_FILES="\
src/sunstone/public/js/plugins/support-tab.js \
src/sunstone/public/js/plugins/zones-tab.js"
SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb"
SUNSTONE_ROUTES_FILES="src/sunstone/routes/oneflow.rb \
src/sunstone/routes/vcenter.rb"
# begin bower
+24
View File
@@ -310,6 +310,17 @@ IM_MAD = [
# arguments = "-c -t 15 -r 0 vmware" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# vCenter Information Driver Manager Configuration
# -r number of retries when monitoring a host
# -t number of threads, i.e. number of hosts monitored at the same time
#-------------------------------------------------------------------------------
#IM_MAD = [
# name = "vcenter",
# executable = "one_im_sh",
# arguments = "-c -t 15 -r 0 vcenter" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# EC2 Information Driver Manager Configuration
# -r number of retries when monitoring a host
@@ -431,6 +442,19 @@ VM_MAD = [
# type = "vmware" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# vCenter Virtualization Driver Manager Configuration
# -r number of retries when monitoring a host
# -t number of threads, i.e. number of hosts monitored at the same time
#-------------------------------------------------------------------------------
#VM_MAD = [
# name = "vcenter",
# executable = "one_vmm_sh",
# arguments = "-p -t 15 -r 0 vcenter -s sh",
# type = "xml" ]
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# EC2 Virtualization Driver Manager Configuration
# -r number of retries when monitoring a host
+217
View File
@@ -0,0 +1,217 @@
#!/usr/bin/env ruby
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
ONE_LOCATION=ENV["ONE_LOCATION"]
if !ONE_LOCATION
RUBY_LIB_LOCATION="/usr/lib/one/ruby"
REMOTES_LOCATION="/var/lib/one/remotes/"
else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby"
REMOTES_LOCATION=ONE_LOCATION+"/var/remotes/"
end
$: << RUBY_LIB_LOCATION
$: << RUBY_LIB_LOCATION+"/cli"
$: << REMOTES_LOCATION+"vmm/vcenter/"
require 'command_parser'
require 'one_helper/onehost_helper'
require 'one_helper/onecluster_helper'
require 'vcenter_driver'
cmd=CommandParser::CmdParser.new(ARGV) do
usage "`onevcenter` <command> [<args>] [<options>]"
version OpenNebulaHelper::ONE_VERSION
helper = OneHostHelper.new
before_proc do
helper.set_client(options)
end
########################################################################
# Global Options
########################################################################
cmd_options=CommandParser::OPTIONS-[CommandParser::VERBOSE]
set :option, cmd_options+OpenNebulaHelper::CLIENT_OPTIONS
VCENTER = {
:name => "vcenter",
:large => "--vcenter vCenter" ,
:description => "The vCenter hostname",
:format => String
}
USER = {
:name => "vuser",
:large => "--vuser username" ,
:description => "The username to interact with vCenter",
:format => String
}
PASS = {
:name => "vpass",
:large => "--vpass password",
:description => "The password for the user",
:format => String
}
############################################################################
# Import clusters
############################################################################
hosts_desc = <<-EOT.unindent
Import vCenter clusters as OpenNebula hosts
EOT
command :hosts, hosts_desc, :options=>[ VCENTER, USER, PASS ] do
if options[:vuser].nil? ||
options[:vpass].nil? ||
options[:vcenter].nil?
STDERR.puts "vCenter connection parameters are mandatory to import"\
" host:\n"\
"\t --vcenter vCenter hostname\n"\
"\t --vuser username to login in vcenter\n"\
"\t --vpass password for the user"
exit -1
end
begin
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
vc = VCenterDriver::VIClient.new_connection(
:user => options[:vuser],
:password => options[:vpass],
:host => options[:vcenter])
STDOUT.print "done!\n\n"
STDOUT.print "Exploring vCenter resources..."
rs = vc.hierarchy
STDOUT.print "done!\n\n"
rs.each {|dc, cluster|
STDOUT.print "Do you want to process datacenter #{dc} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
if cluster.empty?
STDOUT.puts " No clusters found in #{dc}..."
next
end
cluster.each{ |c|
STDOUT.print " * Import cluster #{c} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
r, m = VCenterDriver::VCenterHost.to_one(c, vc)
if r == 0
STDOUT.puts " OpenNebula host #{c} with id #{m}"\
" successfully created."
else
STDOUT.puts " Error: #{m}"
end
STDOUT.puts
}
}
rescue Exception => e
STDOUT.puts "error: #{e.message}"
exit -1
end
exit 0
end
templates_desc = <<-EOT.unindent
Import vCenter VM Templates into OpenNebula
EOT
command :templates, templates_desc, :options=>[ VCENTER, USER, PASS ] do
if options[:vuser].nil? ||
options[:vpass].nil? ||
options[:vcenter].nil?
STDERR.puts "vCenter connection parameters are mandatory to import"\
" VM templates:\n"\
"\t --vcenter vCenter hostname\n"\
"\t --vuser username to login in vcenter\n"\
"\t --vpass password for the user"
exit -1
end
begin
STDOUT.print "\nConnecting to vCenter: #{options[:vcenter]}..."
vc = VCenterDriver::VIClient.new_connection(
:user => options[:vuser],
:password => options[:vpass],
:host => options[:vcenter])
STDOUT.print "done!\n\n"
STDOUT.print "Looking for VM Templates..."
rs = vc.vm_templates
STDOUT.print "done!\n"
rs.each {|dc, tmps|
STDOUT.print "\nDo you want to process datacenter #{dc} [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
if tmps.empty?
STDOUT.print " No VM Templates found in #{dc}...\n\n"
next
end
tmps.each{ |t|
STDOUT.print "\n * VM Template found:\n"\
" - Name : #{t[:name]}\n"\
" - UUID : #{t[:uuid]}\n"\
" - Cluster: #{t[:host]}\n"\
" Import this VM template [y/n]? "
next if STDIN.gets.strip.downcase != 'y'
one_t = ::OpenNebula::Template.new(
::OpenNebula::Template.build_xml, vc.one)
rc = one_t.allocate(t[:one])
if ::OpenNebula.is_error?(rc)
STDOUT.puts " Error creating template: #{rc.message}\n"
else
STDOUT.puts " OpenNebula template #{one_t.id} created!\n"
end
}
}
rescue Exception => e
STDOUT.puts "error: #{e.message}"
exit -1
end
exit 0
end
end
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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
$: << "../../vmm/vcenter/"
require 'vcenter_driver'
host_id = ARGV[4]
if !host_id
exit -1
end
vi_client = VCenterDriver::VIClient.new host_id
vcenter_host = VCenterDriver::VCenterHost.new vi_client
cluster_info = vcenter_host.monitor_cluster
cluster_info << vcenter_host.monitor_host_systems
vm_monitor_info = vcenter_host.monitor_vms
cluster_info << "\nVM_POLL=YES"
cluster_info << "#{vm_monitor_info}" if !vm_monitor_info.empty?
puts cluster_info
+11 -11
View File
@@ -112,7 +112,7 @@ class ActionManager
end
arity=@actions[aname][:method].arity
if arity < 0
# Last parameter is an array
arity = -arity - 1
@@ -145,7 +145,7 @@ class ActionManager
else
thread = nil
end
if thread
thread.kill
@@ -173,17 +173,17 @@ class ActionManager
}
end
end
private
protected
def delete_running_action(action_id)
@action_running.delete(action_id)
end
def get_runable_action
@action_queue.shift
end
def empty_queue
@action_queue.size==0
end
@@ -228,13 +228,13 @@ if __FILE__ == $0
@am.register_action(:SLEEP,method("sleep_action"))
# @am.register_action(:SLEEP,Proc.new{|s,i| p s ; sleep(s)})
@am.register_action(:NOP,method("nop_action"))
def @am.get_runable_action
action = super
puts "getting: #{action.inspect}"
action
end
def @am.delete_running_action(action_id)
puts "deleting: #{action_id}"
super(action_id)
@@ -250,7 +250,7 @@ if __FILE__ == $0
def nop_action
p " - Just an action"
end
end
s = Sample.new
@@ -264,7 +264,7 @@ if __FILE__ == $0
}
s.am.trigger_action(:SLEEP,301,5,301)
s.am.cancel_action(301)
s.am.trigger_action(:FINALIZE,0)
+35 -1
View File
@@ -77,7 +77,8 @@ class VirtualMachineDriver < OpenNebulaDriver
# @option options [Boolean] :threaded (true) enables or disables threads
def initialize(directory, options={})
@options={
:threaded => true
:threaded => true,
:single_host => true
}.merge!(options)
super(directory, @options)
@@ -214,8 +215,17 @@ class VirtualMachineDriver < OpenNebulaDriver
end
private
# Interface to handle the pending events from the ActionManager Interface
def delete_running_action(action_id)
if @options[:single_host]
delete_running_action_single_host(action_id)
else
super(action_id)
end
end
def delete_running_action_single_host(action_id)
action=@action_running[action_id]
if action
@hosts.delete(action[:host])
@@ -224,6 +234,14 @@ private
end
def get_first_runable
if @options[:single_host]
get_first_runable_single_host
else
super
end
end
def get_first_runable_single_host
action_index=nil
@action_queue.each_with_index do |action, index|
if !action.keys.include?(:host)
@@ -255,6 +273,14 @@ private
end
def get_runable_action
if @options[:single_host]
get_runable_action_single_host
else
super
end
end
def get_runable_action_single_host
action_index=get_first_runable
if action_index
@@ -272,6 +298,14 @@ private
end
def empty_queue
if @options[:single_host]
empty_queue_single_host
else
super
end
end
def empty_queue_single_host
get_first_runable==nil
end
end
+10 -1
View File
@@ -224,7 +224,11 @@ module OpenNebula
def deploy(host_id, enforce=false, ds_id=-1)
enforce ||= false
ds_id ||= -1
return call(VM_METHODS[:deploy], @pe_id, host_id.to_i, enforce, ds_id.to_i)
return call(VM_METHODS[:deploy],
@pe_id,
host_id.to_i,
enforce,
ds_id.to_i)
end
# Shutdowns an already deployed VM
@@ -587,6 +591,11 @@ module OpenNebula
self['GID'].to_i
end
# Returns the deploy_id of the VirtualMachine (numeric value)
def deploy_id
self['DEPLOY_ID']
end
private
def action(name)
return Error.new('ID not defined') if !@pe_id
+7 -3
View File
@@ -172,9 +172,13 @@ class OpenNebulaVNC
end
# Proxy data
host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT']
vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD']
host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME']
vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT']
vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD']
if vm_resource['TEMPLATE/ESX_HOST'] # It is behind a vCenter
host = vm_resource['TEMPLATE/ESX_HOST']
end
# Generate token random_str: host:port
random_str = rand(36**20).to_s(36) #random string a-z0-9 length 20
+1
View File
@@ -189,3 +189,4 @@
:routes:
- oneflow
- vcenter
+382 -27
View File
@@ -28,8 +28,18 @@ var create_host_tmpl =
<form id="create_host_form" action="" class="">\
<div class="row">\
<div class="large-6 columns">\
<label for="name">' + tr("Hostname") + '</label>\
<input type="text" name="name" id="name" />\
<label for="host_type">' + tr("Type") + '</label>\
<select id="host_type_mad" name="host_type">\
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="vcenter">' + tr("vCenter") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
<option value="dummy">' + tr("Dummy") + '</option>\
<option value="custom">' + tr("Custom") + '</option>\
</select>\
</div>\
<div class="large-6 columns" id="cluster_select">\
<label for="host_cluster_id">' + tr("Cluster") + '</label>\
@@ -39,17 +49,8 @@ var create_host_tmpl =
</div>\
<div class="row">\
<div class="large-6 columns">\
<label for="host_type">' + tr("Type") + '</label>\
<select id="host_type_mad" name="host_type">\
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
<option value="dummy">' + tr("Dummy") + '</option>\
<option value="custom">' + tr("Custom") + '</option>\
</select>\
<label for="name">' + tr("Hostname") + '</label>\
<input type="text" name="name" id="name" />\
</div>\
<div class="large-6 columns">\
<div class="manager clear row" id="vnm_mads">\
@@ -84,6 +85,7 @@ var create_host_tmpl =
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="vcenter">' + tr("vCenter") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
@@ -105,6 +107,7 @@ var create_host_tmpl =
<option value="kvm">' + tr("KVM") + '</option>\
<option value="xen">' + tr("XEN") + '</option>\
<option value="vmware">' + tr("VMware") + '</option>\
<option value="vcenter">' + tr("vCenter") + '</option>\
<option value="az">' + tr("Microsoft Azure") + '</option>\
<option value="ec2">' + tr("Amazon EC2") + '</option>\
<option value="sl">' + tr("IBM Softlayer") + '</option>\
@@ -121,6 +124,39 @@ var create_host_tmpl =
</div>\
</fieldset>\
</div>\
<div class="row vcenter_credentials hidden">\
<fieldset>\
<legend>'+tr("vCenter")+'</legend>\
<div class="row">\
<div class="large-6 columns">\
<label for="vcenter_user">' + tr("User") + '</label>\
<input type="text" name="vcenter_user" id="vcenter_user" />\
</div>\
<div class="large-6 columns">\
<label for="vcenter_host">' + tr("Hostname") + '</label>\
<input type="text" name="vcenter_host" id="vcenter_host" />\
</div>\
</div>\
<div class="row">\
<div class="large-6 columns">\
<label for="vcenter_password">' + tr("Password") + '</label>\
<input type="password" name="vcenter_password" id="vcenter_password" />\
</div>\
<div class="large-6 columns">\
<br>\
<a class="button radius small right" id="get_vcenter_clusters">'+tr("Get vCenter Clusters")+'</a>\
</div>\
</div>\
<div class="vcenter_clusters">\
</div>\
<div class="row import_vcenter_clusters_div hidden">\
<div class="large-12 columns">\
<br>\
<a class="button radius small right success" id="import_vcenter_clusters">'+tr("Import vCenter Clusters and Templates")+'</a>\
</div>\
</div>\
</fieldset>\
</div>\
<br>\
<div class="form_buttons row">\
<button id="wizard_host_reset_button" class="button secondary radius" type="reset" value="reset">' + tr("Reset") + '</button>\
@@ -145,10 +181,6 @@ var host_actions = {
call : OpenNebula.Host.create,
callback : function(request, response) {
// Reset the create wizard
$create_host_dialog.foundation('reveal', 'close');
$create_host_dialog.empty();
setupCreateHostDialog();
addHostElement(request, response);
notifyCustom(tr("Host created"), " ID: " + response.HOST.ID, false);
},
@@ -431,12 +463,13 @@ function hostElements(){
return getSelectedNodes(dataTable_hosts);
}
function generateCPUProgressBar(host) {
var max_cpu = parseInt(host.HOST_SHARE.MAX_CPU);
function generateCPUProgressBar(host, host_share_flag) {
var host_share = host_share_flag ? host : host.HOST_SHARE;
var max_cpu = parseInt(host_share.MAX_CPU);
var info_str;
var allocated_cpu = parseInt(host.HOST_SHARE.CPU_USAGE);
var allocated_cpu = parseInt(host_share.CPU_USAGE);
if (max_cpu > 0) {
var ratio_allocated_cpu = Math.round((allocated_cpu / max_cpu) * 100);
@@ -447,7 +480,7 @@ function generateCPUProgressBar(host) {
var pb_allocated_cpu = quotaBarHtml(allocated_cpu, max_cpu, info_str);
var real_cpu = parseInt(host.HOST_SHARE.USED_CPU);
var real_cpu = parseInt(host_share.USED_CPU);
if (max_cpu > 0) {
var ratio_real_cpu = Math.round((real_cpu / max_cpu) * 100);
@@ -464,11 +497,12 @@ function generateCPUProgressBar(host) {
}
}
function generateMEMProgressBar(host){
function generateMEMProgressBar(host, host_share_flag) {
var host_share = host_share_flag ? host : host.HOST_SHARE;
// Generate MEM progress bars
var max_mem = parseInt(host.HOST_SHARE.MAX_MEM);
var max_mem = parseInt(host_share.MAX_MEM);
var allocated_mem = parseInt(host.HOST_SHARE.MEM_USAGE);
var allocated_mem = parseInt(host_share.MEM_USAGE);
if (max_mem > 0) {
var ratio_allocated_mem = Math.round((allocated_mem / max_mem) * 100);
@@ -479,7 +513,7 @@ function generateMEMProgressBar(host){
var pb_allocated_mem = quotaBarHtml(allocated_mem, max_mem, info_str);
var real_mem = parseInt(host.HOST_SHARE.USED_MEM);
var real_mem = parseInt(host_share.USED_MEM);
if (max_mem > 0) {
var ratio_real_mem = Math.round((real_mem / max_mem) * 100);
@@ -859,13 +893,60 @@ function updateHostInfo(request,host){
</div>'
}
var esx_info_tab = {
title: tr("ESX"),
icon: "fa-hdd-o",
content : '<div id="datatable_host_esx_info_div" class="row">\
<div class="large-12 columns">\
<table id="datatable_host_esx" class="datatable twelve">\
<thead>\
<tr>\
<th>' + tr("Hostname") + '</th>\
<th>' + tr("Status") + '</th>\
</tr>\
</thead>\
<tbody id="tbody_host_esx">\
</tbody>\
</table>\
</div>\
</div>'
}
//Sunstone.updateInfoPanelTab(info_panel_name,tab_name, new tab object);
Sunstone.updateInfoPanelTab("host_info_panel","host_info_tab",info_tab);
Sunstone.updateInfoPanelTab("host_info_panel","host_monitoring_tab",monitor_tab);
Sunstone.updateInfoPanelTab("host_info_panel","host_vms_tab",vms_info_tab);
if (host_info.TEMPLATE.HYPERVISOR == "vcenter") {
Sunstone.updateInfoPanelTab("host_info_panel","host_esx_tab",esx_info_tab);
}
Sunstone.popUpInfoPanel("host_info_panel", "hosts-tab");
if (host_info.TEMPLATE.HYPERVISOR == "vcenter") {
var dataTable_esx_hosts = $("#datatable_host_esx",main_tabs_context).dataTable({
"bSortClasses" : false,
"bDeferRender": true
});
var host_list_array = [];
$.each(host_info.TEMPLATE.HOST, function(){
// TODO HOST (esx) keys should match HOST_SHARE keys (FREECPU vs FREE_CPU | TOTAL vs MAX)
//var cpu_bars = generateCPUProgressBar(this, true);
//var mem_bars = generateMEMProgressBar(this, true);
host_list_array.push([
this.HOSTNAME,
//cpu_bars.real,
//cpu_bars.allocated,
//mem_bars.real,
//mem_bars.allocated,
this.STATE
]);
});
dataTable_esx_hosts.fnAddData(host_list_array);
delete host_info.TEMPLATE.HOST;
}
var dataTable_host_vMachines = $("#datatable_host_vms", $("#host_info_panel")).dataTable({
"bSortClasses" : false,
"bDeferRender": true,
@@ -931,6 +1012,12 @@ function setupCreateHostDialog(){
$create_host_dialog.addClass("reveal-modal medium").attr("data-reveal", "");
$create_host_dialog.foundation()
$("#wizard_host_reset_button", $create_host_dialog).on("click", function(){
$('#create_host_dialog').html("");
setupCreateHostDialog();
popUpCreateHostDialog();
})
$(".drivers", $create_host_dialog).hide();
$("#host_type_mad", $create_host_dialog).on("change", function(){
@@ -938,12 +1025,276 @@ function setupCreateHostDialog(){
$("#im_mad", $create_host_dialog).val(this.value).change();
if (this.value == "custom") {
$(".vcenter_credentials", $create_host_dialog).hide();
$("#vnm_mads", $create_host_dialog).show();
$("#name", $create_host_dialog).show();
$("#create_host_submit", $create_host_dialog).show();
$(".drivers", $create_host_dialog).show();
} else if (this.value == "vcenter") {
$("#vnm_mads", $create_host_dialog).hide();
$("#name", $create_host_dialog).hide();
$(".vcenter_credentials", $create_host_dialog).show();
$("#create_host_submit", $create_host_dialog).hide();
$(".drivers", $create_host_dialog).hide();
} else {
$(".vcenter_credentials", $create_host_dialog).hide();
$("#vnm_mads", $create_host_dialog).show();
$("#name", $create_host_dialog).show();
$("#create_host_submit", $create_host_dialog).show();
$(".drivers", $create_host_dialog).hide();
}
})
$("#get_vcenter_clusters", $create_host_dialog).on("click", function(){
// TODO notify if credentials empty
$(".vcenter_clusters", $create_host_dialog).html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>')
$.ajax({
url: '/vcenter',
type: "GET",
data: {timeout: false},
dataType: "json",
headers: {
"X_VCENTER_USER": $("#vcenter_user", $create_host_dialog).val(),
"X_VCENTER_PASSWORD": $("#vcenter_password", $create_host_dialog).val(),
"X_VCENTER_HOST": $("#vcenter_host", $create_host_dialog).val()
},
success: function(response){
$("#vcenter_user", $create_host_dialog).attr("disabled", "disabled")
$("#vcenter_password", $create_host_dialog).attr("disabled", "disabled")
$("#vcenter_host", $create_host_dialog).attr("disabled", "disabled")
$("#get_vcenter_clusters", $create_host_dialog).hide();
$(".import_vcenter_clusters_div", $create_host_dialog).show();
var vcenter_container = $(".vcenter_clusters", $create_host_dialog);
vcenter_container.html("");
$('<div class="row">' +
'<div class="large-12 columns">' +
'<p style="color: #999">' + tr("Please select the vCenter Clusters to be imported to OpenNebula. Each vCenter Cluster will be included as a new OpenNebula Host") + '</p>' +
'</div>' +
'</div>').appendTo(vcenter_container)
$.each(response, function(datacenter_name, clusters){
$('<div class="row">' +
'<div class="large-12 columns">' +
'<h5>' +
datacenter_name + ' ' + tr("Clusters") +
'</h5>' +
'</div>' +
'</div>').appendTo(vcenter_container)
if (clusters.length == 0) {
$('<div class="row">' +
'<div class="large-12 columns">' +
'<label>' +
tr("No clusters found in this DataCenter") +
'</label>' +
'</div>' +
'</div>').appendTo(vcenter_container)
} else {
$.each(clusters, function(id, cluster_name){
var row = $('<div class="vcenter_cluster">' +
'<div class="row">' +
'<div class="large-10 columns">' +
'<label>' +
'<input type="checkbox" class="cluster_name"/> ' +
cluster_name +
'</label>' +
'<div class="large-12 columns vcenter_host_response">'+
'</div>'+
'</div>' +
'<div class="large-2 columns vcenter_host_result">'+
'</div>'+
'</div>'+
'<div class="vcenter_templates">'+
'</div>'+
'</div>').appendTo(vcenter_container)
$(".cluster_name", row).data("cluster_name", cluster_name)
$(".cluster_name", row).data("datacenter_name", datacenter_name)
$(".cluster_name", row).on("change", function(){
var templates_container = $(".vcenter_templates", $(this).closest(".vcenter_cluster"));
if ($(this).is(":checked")) {
var path = '/vcenter/' + $(this).data("datacenter_name") + '/cluster/' + $(this).data("cluster_name");
templates_container.html(generateAdvancedSection({
html_id: path,
title: tr("Templates"),
content: '<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>'
}))
$('a', templates_container).trigger("click")
$.ajax({
url: path,
type: "GET",
data: {timeout: false},
dataType: "json",
headers: {
"X_VCENTER_USER": $("#vcenter_user", $create_host_dialog).val(),
"X_VCENTER_PASSWORD": $("#vcenter_password", $create_host_dialog).val(),
"X_VCENTER_HOST": $("#vcenter_host", $create_host_dialog).val()
},
success: function(response){
$(".content", templates_container).html("");
$.each(response, function(id, template){
var trow = $('<div class="vcenter_template">' +
'<div class="row">' +
'<div class="large-10 columns">' +
'<label>' +
'<input type="checkbox" class="template_name" checked/> ' +
template.name + '&emsp;<span style="color: #999">' + template.uuid + '</span>' +
'</label>' +
'<div class="large-12 columns vcenter_template_response">'+
'</div>'+
'</div>' +
'<div class="large-2 columns vcenter_template_result">'+
'</div>'+
'</div>'+
'<div class="vcenter_templates">'+
'</div>'+
'</div>').appendTo($(".content", templates_container))
$(".template_name", trow).data("template_name", template.name)
$(".template_name", trow).data("one_template", template.one)
});
},
error: function(response){
templates_container.html("");
onError({}, OpenNebula.Error(response));
}
});
} else {
templates_container.html("");
}
})
});
}
});
},
error: function(response){
$(".vcenter_clusters", $create_host_dialog).html('')
onError({}, OpenNebula.Error(response));
}
});
return false;
})
$("#import_vcenter_clusters", $create_host_dialog).on("click", function(){
$(this).hide();
var cluster_id = $('#host_cluster_id .resource_list_select', $create_host_dialog).val();
if (!cluster_id) cluster_id = "-1";
$.each($(".cluster_name:checked", $create_host_dialog), function(){
var cluster_context = $(this).closest(".vcenter_cluster");
$(".vcenter_host_result:not(.success)", cluster_context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>');
var host_json = {
"host": {
"name": $(this).data("cluster_name"),
"vm_mad": "vcenter",
"vnm_mad": "dummy",
"im_mad": "vcenter",
"cluster_id": cluster_id
}
};
OpenNebula.Host.create({
timeout: true,
data: host_json,
success: function(request, response) {
OpenNebula.Helper.clear_cache("HOST");
$(".vcenter_host_result", cluster_context).addClass("success").html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-check fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_host_response", cluster_context).html('<p style="font-size:12px" class="running-color">'+
tr("Host created successfully")+' ID:'+response.HOST.ID+
'</p>');
var template_raw =
"VCENTER_USER=\"" + $("#vcenter_user", $create_host_dialog).val() + "\"\n" +
"VCENTER_PASSWORD=\"" + $("#vcenter_password", $create_host_dialog).val() + "\"\n" +
"VCENTER_HOST=\"" + $("#vcenter_host", $create_host_dialog).val() + "\"\n";
Sunstone.runAction("Host.update_template", response.HOST.ID, template_raw);
addHostElement(request, response);
$.each($(".template_name:checked", cluster_context), function(){
var template_context = $(this).closest(".vcenter_template");
$(".vcenter_template_result:not(.success)", template_context).html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-spinner fa-spin fa-stack-1x fa-inverse"></i>'+
'</span>');
var template_json = {
"vmtemplate": {
"template_raw": $(this).data("one_template")
}
};
OpenNebula.Template.create({
timeout: true,
data: template_json,
success: function(request, response) {
OpenNebula.Helper.clear_cache("VMTEMPLATE");
$(".vcenter_template_result", template_context).addClass("success").html(
'<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-check fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_template_response", template_context).html('<p style="font-size:12px" class="running-color">'+
tr("Template created successfully")+' ID:'+response.VMTEMPLATE.ID+
'</p>');
},
error: function (request, error_json){
$(".vcenter_template_result", template_context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-warning fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_template_response", template_context).html('<p style="font-size:12px" class="error-color">'+
(error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+
'</p>');
}
});
})
},
error: function (request, error_json){
$(".vcenter_host_result", context).html('<span class="fa-stack fa-2x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-warning fa-stack-1x fa-inverse"></i>'+
'</span>');
$(".vcenter_host_response", context).html('<p style="font-size:12px" class="error-color">'+
(error_json.error.message || tr("Cannot contact server: is it running and reachable?"))+
'</p>');
}
});
})
return false
});
// Show custom driver input only when custom is selected in selects
$('input[name="custom_vmm_mad"],'+
'input[name="custom_im_mad"],'+
@@ -1007,13 +1358,17 @@ function setupCreateHostDialog(){
//Open creation dialogs
function popUpCreateHostDialog(){
$create_host_dialog.foundation('reveal', 'close');
$create_host_dialog.empty();
setupCreateHostDialog();
var cluster_id = $('#host_cluster_id .resource_list_select',$('div#create_host_dialog')).val();
if (!cluster_id) cluster_id = "-1";
insertSelectOptions('#host_cluster_id',$('div#create_host_dialog'), "Cluster", cluster_id, false);
$('div#create_host_dialog').foundation('reveal', 'open');
$("input#name",$('div#create_host_dialog')).focus();
$("#create_host_dialog").foundation('reveal', 'open');
$("input#name",$("#create_host_dialog")).focus();
return false;
}
+42 -18
View File
@@ -784,16 +784,17 @@ function generate_capacity_tab_content() {
'<input type="radio" name="hypervisor" value="kvm" id="kvmRadio"><label for="kvmRadio">'+tr("KVM")+'</label>'+
'<input type="radio" name="hypervisor" value="vmware" id="vmwareRadio"><label for="vmwareRadio">'+tr("VMware")+'</label>'+
'<input type="radio" name="hypervisor" value="xen" id="xenRadio"><label for="xenRadio">'+tr("Xen")+'</label>'+
'<input type="radio" name="hypervisor" value="vcenter" id="vcenterRadio"><label for="vcenterRadio">'+tr("vCenter")+'</label>'+
'</div>'+
'</div>'+
'<div class="row vm_param">'+
'<div class="large-8 columns">'+
'<div class="large-6 columns">'+
'<label for="DESCRIPTION">'+tr("Description")+'\
<span class="tip">'+tr("Description of the template")+'</span>\
</label>'+
'<textarea type="text" id="DESCRIPTION" name="DESCRIPTION" style="height: 70px;"/>'+
'</div>'+
'<div class="large-4 columns">'+
'<div class="large-6 columns">'+
'<div class="row">'+
'<div class="large-6 columns">'+
'<label for="LOGO">'+tr("Logo")+'\
@@ -818,6 +819,14 @@ function generate_capacity_tab_content() {
'</div>'+
'</div>'+
'</div>'+
'<div class="row hypervisor only_vcenter" style="display: none;">'+
'<div class="large-6 columns">'+
'<label for="vcenter_template_uuid">'+tr("vCenter Template UUID")+'\
<span class="tip">'+tr("")+'</span>\
</label>'+
'<input type="text" id="vcenter_template_uuid" name="name" required/>'+
'</div>'+
'</div>'+
'<br>'+
generate_capacity_inputs();
@@ -2038,15 +2047,15 @@ function wizard_tab_dd(){
}
if (Config.isTemplateCreationTabEnabled('storage')){
str += "<dd><a href='#storageTab'><i class='fa fa-tasks'></i><br>"+tr("Storage")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#storageTab'><i class='fa fa-tasks'></i><br>"+tr("Storage")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('network')){
str += "<dd><a href='#networkTab'><i class='fa fa-globe'></i><br>"+tr("Network")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#networkTab'><i class='fa fa-globe'></i><br>"+tr("Network")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('os_booting')){
str += "<dd><a href='#osTab'><i class='fa fa-power-off'></i><br>"+tr("OS Booting")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#osTab'><i class='fa fa-power-off'></i><br>"+tr("OS Booting")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('input_output')){
@@ -2054,7 +2063,7 @@ function wizard_tab_dd(){
}
if (Config.isTemplateCreationTabEnabled('context')){
str += "<dd><a href='#contextTab'><i class='fa fa-folder'></i><br>"+tr("Context")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#contextTab'><i class='fa fa-folder'></i><br>"+tr("Context")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('scheduling')){
@@ -2542,8 +2551,8 @@ function wizard_tab_content(){
'<div class="row">'+
'<div class="large-12 columns text-center">'+
'<input type="radio" name="graphics_type" ID="radioVncType" value="VNC"><label for="radioVncType"> VNC </label>'+
'<input type="radio" name="graphics_type" ID="radioSdlType" value="SDL"><label for="radioSdlType"> SDL </label>'+
'<input type="radio" name="graphics_type" ID="radioSpiceType" value="SPICE"><label for="radioSpiceType"> SPICE </label>'+
'<input type="radio" name="graphics_type" ID="radioSdlType" value="SDL" class="hypervisor only_kvm only_vmware only_xen" ><label class="hypervisor only_kvm only_vmware only_xen" for="radioSdlType"> SDL </label>'+
'<input type="radio" name="graphics_type" ID="radioSpiceType" value="SPICE" class="hypervisor only_kvm only_vmware only_xen" ><label class="hypervisor only_kvm only_vmware only_xen" for="radioSpiceType"> SPICE </label>'+
'</div>'+
'</div>'+
'<br>'+
@@ -2563,14 +2572,14 @@ function wizard_tab_content(){
'</label>'+
'<input type="text" id="PORT" name="port" />'+
'</div>'+
'<div class="large-6 columns">'+
'<div class="large-6 columns hypervisor only_kvm only_vmware only_xen">'+
'<label for="KEYMAP">'+tr("Keymap")+
'<span class="tip">'+tr("Keyboard configuration locale to use in the VNC/SPICE display")+'</span>'+
'</label>'+
'<input type="text" id="KEYMAP" name="keymap" />'+
'</div>'+
'</div>'+
'<div class="row vm_param">'+
'<div class="row hypervisor only_kvm only_vmware only_xen">'+
'<div class="large-12 columns">'+
'<label for="PASSWD">'+tr("Password")+
'<span class="tip">'+tr("Password for the VNC/SPICE server")+'</span>'+
@@ -2580,7 +2589,7 @@ function wizard_tab_content(){
'</div>'+
'</fieldset>'+
'</div>'+
'<div class="large-6 columns inputs">'+
'<div class="large-6 columns inputs hypervisor only_kvm only_vmware only_xen">'+
'<fieldset>'+
'<legend>'+tr("Inputs")+'</legend>'+
'<div class="row">'+
@@ -2905,7 +2914,7 @@ function wizard_tab_content(){
'</div>'+
'</div>'+
'</fieldset>'+
'<fieldset>'+
'<fieldset class="hypervisor only_kvm only_vmware only_xen">'+
'<legend>'+tr("Datastore Requirements")+'</legend>'+
'<div class="row vm_param">'+
'<div class="large-12 columns">'+
@@ -2943,7 +2952,7 @@ function wizard_tab_content(){
'</div>'+
'</div>'+
'</fieldset>'+
'<fieldset class="ds_rank">'+
'<fieldset class="ds_rank hypervisor only_kvm only_vmware only_xen">'+
'<legend>'+tr("Datastore Rank")+'</legend>'+
'<div class="row">'+
'<div class="large-12 columns text-center">'+
@@ -2986,7 +2995,7 @@ function wizard_tab_content(){
'<div id="rawTab" class="wizard_tab content">'+
'<div class="row">'+
'<div class="large-12 columns">'+
'<fieldset>'+
'<fieldset class="hypervisor only_xen only_kvm only_vmware">'+
'<legend>'+tr("RAW data")+'</legend>'+
'<div class="row">'+
'<div class="large-4 columns">'+
@@ -4023,7 +4032,14 @@ function build_template(dialog){
addSectionJSON(vm_json,$('#capacityTab',dialog));
vm_json["DESCRIPTION"] = $('#DESCRIPTION',$('#capacityTab',dialog)).val();
vm_json["LOGO"] = $('#LOGO',$('#capacityTab',dialog)).val();
vm_json["HYPERVISOR"] = $('input[name="hypervisor"]:checked', $('#capacityTab',dialog)).val();
var hypervisor = $('input[name="hypervisor"]:checked', $('#capacityTab',dialog)).val();
vm_json["HYPERVISOR"] = hypervisor;
if (hypervisor == "vcenter") {
vm_json["PUBLIC_CLOUD"] = {
"TYPE": "vcenter",
"VM_TEMPLATE": $("#vcenter_template_uuid", dialog).val()
}
}
//
// OS
@@ -4097,7 +4113,10 @@ function build_template(dialog){
// HYBRID
vm_json["PUBLIC_CLOUD"] = [];
if ($.isEmptyObject(vm_json["PUBLIC_CLOUD"])) {
vm_json["PUBLIC_CLOUD"] = [];
}
vm_json["EC2"] = [];
$('.provider',dialog).each(function(){
@@ -4418,16 +4437,21 @@ var fillTemplatePopUp = function(template, dialog){
//
function fillProviderTab(provider, provider_type){
if (provider_type == "vcenter") {
$("#vcenter_template_uuid", dialog).val(provider["VM_TEMPLATE"])
} else {
if (number_of_providers > 0) {
$("#tf_btn_hybrid", dialog).trigger("click");
}
number_of_providers++;
}
var context = $(".provider", dialog).last();
$("input.hybridRadio[value='"+provider_type+"']", context).trigger("click");
autoFillInputs(provider, context);
number_of_providers++;
}
var number_of_providers = 0;
@@ -4441,7 +4465,7 @@ var fillTemplatePopUp = function(template, dialog){
});
}
else if (providers instanceof Object) {
fillProviderTab(providers, this.TYPE.toLowerCase());
fillProviderTab(providers, providers.TYPE.toLowerCase());
}
delete template.PUBLIC_CLOUD
+89
View File
@@ -0,0 +1,89 @@
# -------------------------------------------------------------------------- #
# 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. #
#--------------------------------------------------------------------------- #
if !ONE_LOCATION
REMOTES_LOCATION="/var/lib/one/remotes"
else
REMOTES_LOCATION=ONE_LOCATION+"/var/remotes"
end
# TODO vcenter_driver should be stored in RUBY_LIB_LOCATION
$: << REMOTES_LOCATION+"/vmm/vcenter/"
require 'vcenter_driver'
helpers do
def vcenter_client
vuser = request.env['HTTP_X_VCENTER_USER']
vpass = request.env['HTTP_X_VCENTER_PASSWORD']
vhost = request.env['HTTP_X_VCENTER_HOST']
if vuser.nil? || vpass.nil? || vhost.nil?
msg = "You have to provide the vCenter username, password and hostname"
logger.error("[vCenter] " + msg)
error = Error.new(msg)
error 404, error.to_json
end
return VCenterDriver::VIClient.new_connection(
:user => vuser,
:password => vpass,
:host => vhost)
end
# def af_format_response(resp)
# if CloudClient::is_error?(resp)
# logger.error("[OneFlow] " + resp.to_s)
#
# error = Error.new(resp.to_s)
# error resp.code.to_i, error.to_json
# else
# body resp.body.to_s
# end
# end
end
get '/vcenter' do
begin
rs = vcenter_client.hierarchy
[200, rs.to_json]
rescue Exception => e
logger.error("[vCenter] " + e.message)
error = Error.new(e.message)
error 403, error.to_json
end
end
get '/vcenter/:datacenter/cluster/:name' do
begin
rs = vcenter_client.vm_templates
templates = rs[params[:datacenter]]
if templates.nil?
msg = "Datacenter " + params[:datacenter] + "not found"
logger.error("[vCenter] " + msg)
error = Error.new(msg)
error 404, error.to_json
end
ctemplates = templates.select{|t| t[:host] == params[:name]}
[200, ctemplates.to_json]
rescue Exception => e
logger.error("[vCenter] " + e.message)
error = Error.new(e.message)
error 403, error.to_json
end
end
+7 -2
View File
@@ -901,7 +901,8 @@ opts = GetoptLong.new(
[ '--retries', '-r', GetoptLong::OPTIONAL_ARGUMENT ],
[ '--threads', '-t', GetoptLong::OPTIONAL_ARGUMENT ],
[ '--local', '-l', GetoptLong::REQUIRED_ARGUMENT ],
[ '--shell', '-s', GetoptLong::REQUIRED_ARGUMENT ]
[ '--shell', '-s', GetoptLong::REQUIRED_ARGUMENT ],
[ '--parallel', '-p', GetoptLong::NO_ARGUMENT ]
)
hypervisor = ''
@@ -909,6 +910,7 @@ retries = 0
threads = 15
shell = 'bash'
local_actions = {}
single_host = true
begin
opts.each do |opt, arg|
@@ -921,6 +923,8 @@ begin
local_actions=OpenNebulaDriver.parse_actions_list(arg)
when '--shell'
shell = arg
when '--parallel'
single_host = false
end
end
rescue Exception => e
@@ -937,6 +941,7 @@ exec_driver = ExecDriver.new(hypervisor,
:concurrency => threads,
:retries => retries,
:local_actions => local_actions,
:shell => shell)
:shell => shell,
:single_host => single_host)
exec_driver.start_driver
+1 -1
View File
@@ -25,6 +25,6 @@ fi
LOCAL_ACTIONS="deploy,shutdown,reboot,cancel,save,restore,migrate,poll,pre"
LOCAL_ACTIONS="${LOCAL_ACTIONS},post,clean"
LOCAL_ACTIONS="${LOCAL_ACTIONS},snapshotcreate,snapshotrevert,snapshotdelete"
LOCAL_ACTIONS="${LOCAL_ACTIONS},attach_nic,detach_nic"
LOCAL_ACTIONS="${LOCAL_ACTIONS},attach_nic,detach_nic,reset"
exec $MAD_LOCATION/one_vmm_exec -l $LOCAL_ACTIONS $*
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
+47
View File
@@ -0,0 +1,47 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
host = ARGV[1]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
VCenterDriver::VCenterVm.cancel(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Cancel of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
+53
View File
@@ -0,0 +1,53 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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'
require 'opennebula'
dfile = ARGV[0]
host = ARGV[1]
vm_id = ARGV[2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
deploy_id = vm.deploy_id
begin
puts VCenterDriver::VCenterVm.deploy(File.read(dfile),
lcm_state,
deploy_id,
host)
rescue Exception => e
STDERR.puts "Deploy of VM #{vm_id} on host #{host} with #{dfile} failed " +
"due to \"#{e.message}\""
exit -1
end
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
+20
View File
@@ -0,0 +1,20 @@
#!/bin/bash
# -------------------------------------------------------------------------- #
# Copyright 2002-2014, OpenNebula Project (OpenNebula.org), C12G Labs #
# #
# 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. #
#--------------------------------------------------------------------------- #
SCRIPT_NAME=$(basename $0)
echo "Action $SCRIPT_NAME not supported" 1>&2
+43
View File
@@ -0,0 +1,43 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
host = ARGV[1]
host_id = VCenterDriver::VIClient.translate_hostname(host)
vi_client = VCenterDriver::VIClient.new host_id
vm = vi_client.find_vm_template(deploy_id)
vm = VCenterDriver::VCenterVm.new(vi_client, vm)
vm.monitor
puts vm.info
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
host = ARGV[1]
begin
VCenterDriver::VCenterVm.reboot(deploy_id, host)
rescue Exception => e
STDERR.puts "Guest reboot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
host = ARGV[1]
begin
VCenterDriver::VCenterVm.reset(deploy_id, host)
rescue Exception => e
STDERR.puts "Reset of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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'
host = ARGV[-1]
deploy_id = ARGV[2]
begin
VCenterDriver::VCenterVm.resume(deploy_id, host)
rescue Exception => e
STDERR.puts "Restore of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
+49
View File
@@ -0,0 +1,49 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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'
require 'opennebula'
deploy_id = ARGV[0]
file = ARGV[1]
host = ARGV[2]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
puts VCenterDriver::VCenterVm.save(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Save of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
+48
View File
@@ -0,0 +1,48 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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'
require 'opennebula'
deploy_id = ARGV[0]
host = ARGV[1]
vm_id = ARGV[-2]
vm = OpenNebula::VirtualMachine.new_with_id(vm_id, OpenNebula::Client.new)
vm.info
lcm_state = vm.lcm_state_str
begin
VCenterDriver::VCenterVm.shutdown(deploy_id, host, lcm_state)
rescue Exception => e
STDERR.puts "Shutdown of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
snapshot_name = ARGV[1]
host = ARGV[3]
begin
puts VCenterDriver::VCenterVm.create_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
snapshot_name = ARGV[1]
host = ARGV[3]
begin
VCenterDriver::VCenterVm.delete_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} failed " +
"due to \"#{e.message}\""
exit -1
end
@@ -0,0 +1,44 @@
#!/usr/bin/env ruby
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
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]
snapshot_name = ARGV[1]
host = ARGV[3]
begin
VCenterDriver::VCenterVm.revert_snapshot(deploy_id,
host,
snapshot_name)
rescue Exception => e
STDERR.puts "Snapshot of VM #{deploy_id} on host #{host} could not be " +
"reverted due to \"#{e.message}\""
exit -1
end
@@ -0,0 +1,783 @@
# ---------------------------------------------------------------------------- #
# 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. #
# ---------------------------------------------------------------------------- #
# -------------------------------------------------------------------------#
# Set up the environment for the driver #
# -------------------------------------------------------------------------#
ONE_LOCATION = ENV["ONE_LOCATION"] if !defined?(ONE_LOCATION)
if !ONE_LOCATION
BIN_LOCATION = "/usr/bin" if !defined?(BIN_LOCATION)
LIB_LOCATION = "/usr/lib/one" if !defined?(LIB_LOCATION)
ETC_LOCATION = "/etc/one/" if !defined?(ETC_LOCATION)
VAR_LOCATION = "/var/lib/one" if !defined?(VAR_LOCATION)
else
BIN_LOCATION = ONE_LOCATION + "/bin" if !defined?(BIN_LOCATION)
LIB_LOCATION = ONE_LOCATION + "/lib" if !defined?(LIB_LOCATION)
ETC_LOCATION = ONE_LOCATION + "/etc/" if !defined?(ETC_LOCATION)
VAR_LOCATION = ONE_LOCATION + "/var/" if !defined?(VAR_LOCATION)
end
ENV['LANG'] = 'C'
$: << LIB_LOCATION+'/ruby/vendors/rbvmomi/lib'
$: << LIB_LOCATION+'/ruby'
require 'rbvmomi'
require 'yaml'
require 'opennebula'
module VCenterDriver
################################################################################
# This class represents a VCenter connection and an associated OpenNebula client
# The connection is associated to the VCenter backing a given OpenNebula host.
# For the VCenter driver each OpenNebula host represents a VCenter cluster
################################################################################
class VIClient
attr_reader :vim, :one, :root, :cluster, :user, :pass, :host
############################################################################
# Initializr the VIClient, and creates an OpenNebula client. The parameters
# are obtained from the associated OpenNebula host
# @param hid [Integer] The OpenNebula host id with VCenter attributes
############################################################################
def initialize(hid)
initialize_one
@one_host = ::OpenNebula::Host.new_with_id(hid, @one)
rc = @one_host.info
if ::OpenNebula.is_error?(rc)
raise "Error getting host information: #{rc.message}"
end
connection = {
:host => @one_host["TEMPLATE/VCENTER_HOST"],
:user => @one_host["TEMPLATE/VCENTER_USER"],
:password => @one_host["TEMPLATE/VCENTER_PASSWORD"]
}
initialize_vim(connection)
@root.childEntity.each {|dc|
ccrs = dc.hostFolder.childEntity.grep(
RbVmomi::VIM::ClusterComputeResource)
next if ccrs.nil?
@cluster = ccrs.find{ |ccr| @one_host.name == ccr.name }
(@dc = dc; break) if @cluster
}
if @dc.nil? || @cluster.nil?
raise "Cannot find DataCenter or ClusterComputeResource for host."
end
end
########################################################################
# Initialize a VIConnection based just on the VIM parameters. The
# OpenNebula client is also initilialize
########################################################################
def self.new_connection(user_opts)
conn = allocate
conn.initialize_one
conn.initialize_vim(user_opts)
return conn
end
########################################################################
# The associated resource pool for this connection
########################################################################
def resource_pool
return @cluster.resourcePool
end
########################################################################
# Searches the associated vmFolder of the DataCenter for the current
# connection. Returns a RbVmomi::VIM::VirtualMachine or nil if not found
# @param uuid [String] the UUID of the VM or VM Template
########################################################################
def find_vm_template(uuid)
vms = @dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine)
return vms.find{ |v| v.config.uuid == uuid }
end
########################################################################
# Builds a hash with the DataCenter / ClusterComputeResource hierarchy
# for this VCenter.
# @return [Hash] in the form
# {dc_name [String] => ClusterComputeResources Names [Array - String]}
########################################################################
def hierarchy
vc_hosts = {}
@root.childEntity.each { |dc|
ccrs = dc.hostFolder.childEntity.grep(
RbVmomi::VIM::ClusterComputeResource)
vc_hosts[dc.name] = ccrs.collect { |c| c.name }
}
return vc_hosts
end
########################################################################
# Builds a hash with the Datacenter / VM Templates for this VCenter
# @return [Hash] in the form
# { dc_name [String] => }
########################################################################
def vm_templates
vm_templates = {}
@root.childEntity.each { |dc|
vms = dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine)
tmp = vms.select { |v| v.config.template == true }
one_tmp = []
tmp.each { |t|
vi_tmp = VCenterVm.new(self, t)
one_tmp << {
:name => vi_tmp.vm.name,
:uuid => vi_tmp.vm.config.uuid,
:host => vi_tmp.vm.runtime.host.parent.name,
:one => vi_tmp.to_one
}
}
vm_templates[dc.name] = one_tmp
}
return vm_templates
end
def self.translate_hostname(hostname)
host_pool = OpenNebula::HostPool.new(::OpenNebula::Client.new())
rc = host_pool.info
raise "Could not find host #{hostname}" if OpenNebula.is_error?(rc)
host = host_pool.select {|host_element| host_element.name==hostname }
return host.first.id
end
############################################################################
# Initialize an OpenNebula connection with the default ONE_AUTH
############################################################################
def initialize_one
begin
@one = ::OpenNebula::Client.new()
rescue Exception => e
raise "Error initializing OpenNebula client: #{e.message}"
end
end
############################################################################
# Initialize a connection with vCenter. Options
# @param options[Hash] with:
# :user => The vcenter user
# :password => Password for the user
# :host => vCenter hostname or IP
# :insecure => SSL (optional, defaults to true)
############################################################################
def initialize_vim(user_opts={})
opts = {
:insecure => true
}.merge(user_opts)
@user = opts[:user]
@pass = opts[:password]
@host = opts[:host]
begin
@vim = RbVmomi::VIM.connect(opts)
@root = @vim.root
rescue Exception => e
raise "Error connecting to #{@host}: #{e.message}"
end
end
end
################################################################################
# This class is an OpenNebula hosts that abstracts a vCenter cluster. It
# includes the functionality needed to monitor the cluster and report the ESX
# hosts and VM status of the cluster.
################################################################################
class VCenterHost < ::OpenNebula::Host
attr_reader :vc_client, :vc_root, :cluster, :host, :client
############################################################################
# Initialize the VCenterHost by looking for the associated objects of the
# VIM hierarchy
# client [VIClient] to interact with the associated vCenter
############################################################################
def initialize(client)
@client = client
@cluster = client.cluster
@resource_pool = client.resource_pool
end
########################################################################
# Creates an OpenNebula host representing a cluster in this VCenter
# @param cluster_name[String] the name of the cluster in the vcenter
# @param client [VIClient] to create the host
# @return In case of success [0, host_id] or [-1, error_msg]
########################################################################
def self.to_one(cluster_name, client)
one_host = ::OpenNebula::Host.new(::OpenNebula::Host.build_xml,
client.one)
rc = one_host.allocate(cluster_name, 'vcenter', 'vcenter', 'dummy',
::OpenNebula::ClusterPool::NONE_CLUSTER_ID)
return -1, rc.message if ::OpenNebula.is_error?(rc)
template = "VCENTER_HOST=\"#{client.host}\"\n"\
"VCENTER_PASSWORD=\"#{client.pass}\"\n"\
"VCENTER_USER=\"#{client.user}\"\n"
rc = one_host.update(template, false)
if ::OpenNebula.is_error?(rc)
error = rc.message
rc = one_host.delete
if ::OpenNebula.is_error?(rc)
error << ". Host #{cluster_name} could not be"\
" deleted: #{rc.message}."
end
return -1, error
end
return 0, one_host.id
end
############################################################################
# Generate an OpenNebula monitor string for this host. Reference:
# https://www.vmware.com/support/developer/vc-sdk/visdk25pubs/ReferenceGuide/vim.ComputeResource.Summary.html
# - effectiveCpu: Effective CPU resources (in MHz) available to run
# VMs. This is the aggregated from all running hosts excluding hosts in
# maintenance mode or unresponsive are not counted.
# - effectiveMemory: Effective memory resources (in MB) available to run
# VMs. Equivalente to effectiveCpu.
# - numCpuCores: Number of physical CPU cores.
# - numEffectiveHosts: Total number of effective hosts.
# - numHosts:Total number of hosts.
# - totalCpu: Aggregated CPU resources of all hosts, in MHz.
# - totalMemory: Aggregated memory resources of all hosts, in bytes.
############################################################################
def monitor_cluster
#Load the host systems
summary = @cluster.summary
mhz_core = summary.totalCpu.to_f / summary.numCpuCores.to_f
eff_core = summary.effectiveCpu.to_f / mhz_core
free_cpu = sprintf('%.2f', eff_core * 100).to_f
total_cpu = summary.numCpuCores.to_f * 100
used_cpu = sprintf('%.2f', total_cpu - free_cpu).to_f
total_mem = summary.totalMemory.to_i / 1024
free_mem = summary.effectiveMemory.to_i * 1024
str_info = ""
# System
str_info << "HYPERVISOR=vcenter\n"
str_info << "PUBLIC_CLOUD=YES\n"
str_info << "TOTALHOST=" << summary.numHosts.to_s << "\n"
str_info << "AVAILHOST=" << summary.numEffectiveHosts.to_s << "\n"
# CPU
str_info << "CPUSPEED=" << mhz_core.to_s << "\n"
str_info << "TOTALCPU=" << total_cpu.to_s << "\n"
str_info << "USEDCPU=" << used_cpu.to_s << "\n"
str_info << "FREECPU=" << free_cpu.to_s << "\n"
# Memory
str_info << "TOTALMEMORY=" << total_mem.to_s << "\n"
str_info << "FREEMEMORY=" << free_mem.to_s << "\n"
str_info << "USEDMEMORY=" << (total_mem - free_mem).to_s
end
############################################################################
# Generate a template with information for each ESX Host. Reference:
# http://pubs.vmware.com/vi-sdk/visdk250/ReferenceGuide/vim.HostSystem.html
# - Summary: Basic information about the host, including connection state
# - hardware: Hardware configuration of the host. This might not be
# available for a disconnected host.
# - quickStats: Basic host statistics.
############################################################################
def monitor_host_systems
host_info = ""
@cluster.host.each{|h|
next if h.runtime.connectionState != "connected"
summary = h.summary
hw = summary.hardware
stats = summary.quickStats
total_cpu = hw.numCpuCores * 100
used_cpu = (stats.overallCpuUsage.to_f / hw.cpuMhz.to_f) * 100
used_cpu = sprintf('%.2f', used_cpu).to_f # Trim precission
free_cpu = total_cpu - used_cpu
total_memory = hw.memorySize/1024
used_memory = stats.overallMemoryUsage*1024
free_memory = total_memory - used_memory
host_info << "\nHOST=["
host_info << "STATE=on,"
host_info << "HOSTNAME=\"" << h.name.to_s << "\","
host_info << "MODELNAME=\"" << hw.cpuModel.to_s << "\","
host_info << "CPUSPEED=" << hw.cpuMhz.to_s << ","
host_info << "MAX_CPU=" << total_cpu.to_s << ","
host_info << "USED_CPU=" << used_cpu.to_s << ","
host_info << "FREE_CPU=" << free_cpu.to_s << ","
host_info << "MAX_MEMORY=" << total_memory.to_s << ","
host_info << "USED_MEMORY=" << used_memory.to_s << ","
host_info << "FREE_MEMORY=" << free_memory.to_s
host_info << "]"
}
return host_info
end
def monitor_vms
str_info = ""
@resource_pool.vm.each { |v|
name = v.name
number = -1
number = name.split('-').last if (name =~ /^one-\d*$/)
vm = VCenterVm.new(@client, v)
vm.monitor
str_info << "\nVM = ["
str_info << "ID=#{number},"
str_info << "DEPLOY_ID=\"#{name}\","
str_info << "POLL=\"#{vm.info}\"]"
}
return str_info
end
end
################################################################################
# This class is a high level abstraction of a VI VirtualMachine class with
# OpenNebula semantics.
################################################################################
class VCenterVm
attr_reader :vm
############################################################################
# Creates a new VIVm using a RbVmomi::VirtualMachine object
# @param client [VCenterClient] client to connect to vCenter
# @param vm_vi [RbVmomi::VirtualMachine] it will be used if not nil
########################################################################
def initialize(client, vm_vi )
@vm = vm_vi
@client = client
@used_cpu = 0
@used_memory = 0
@net_rx = 0
@net_tx = 0
end
############################################################################
# Deploys a VM
# @xml_text XML repsentation of the VM
############################################################################
def self.deploy(xml_text, lcm_state, deploy_id, hostname)
if lcm_state == "BOOT"
return clone_vm(xml_text)
else
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.PowerOnVM_Task.wait_for_completion
return vm.config.uuid
end
end
############################################################################
# Cancels a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.cancel(deploy_id, hostname, lcm_state)
case lcm_state
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
shutdown(deploy_id, hostname, lcm_state)
when "CANCEL", "LCM_INIT"
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
begin
vm.PowerOffVM_Task.wait_for_completion
rescue
end
vm.Destroy_Task.wait_for_completion
end
end
############################################################################
# Saves a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.save(deploy_id, hostname, lcm_state)
case lcm_state
when "SAVE_MIGRATE"
raise "Migration between vCenters cluster not supported"
when "SAVE_SUSPEND", "SAVE_STOP"
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.SuspendVM_Task.wait_for_completion
end
end
############################################################################
# Resumes a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.resume(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.PowerOnVM_Task.wait_for_completion
end
############################################################################
# Reboots a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.reboot(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.RebootGuest.wait_for_completion
end
############################################################################
# Resets a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.reset(deploy_id, hostname)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
vm.ResetVM_Task.wait_for_completion
end
############################################################################
# Shutdown a VM
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
############################################################################
def self.shutdown(deploy_id, hostname, lcm_state)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
case lcm_state
when "SHUTDOWN"
begin
vm.ShutdownGuest.wait_for_completion
rescue
end
vm.PowerOffVM_Task.wait_for_completion
vm.Destroy_Task.wait_for_completion
when "SHUTDOWN_POWEROFF", "SHUTDOWN_UNDEPLOY"
begin
vm.ShutdownGuest.wait_for_completion
rescue
end
vm.PowerOffVM_Task.wait_for_completion
end
end
############################################################################
# Create VM snapshot
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
# @param snaphot_name name of the snapshot
############################################################################
def self.create_snapshot(deploy_id, hostname, snapshot_name)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
snapshot_hash = {
:name => snapshot_name,
:description => "OpenNebula Snapshot of VM #{deploy_id}",
:memory => true,
:quiesce => true
}
vm = connection.find_vm_template(deploy_id)
vm.CreateSnapshot_Task(snapshot_hash).wait_for_completion
return snapshot_name
end
############################################################################
# Delete VM snapshot
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
# @param snaphot_name name of the snapshot
############################################################################
def self.delete_snapshot(deploy_id, hostname, snapshot_name)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
snapshot = vm.snapshot.rootSnapshotList.find {|s|
s.name == snapshot_name
}.snapshot
delete_snapshot_hash = {
:_this => snapshot,
:removeChildren => true
}
snapshot.RemoveSnapshot_Task(delete_snapshot_hash).wait_for_completion
end
############################################################################
# Revert VM snapshot
# @param deploy_id vcenter identifier of the VM
# @param hostname name of the host (equals the vCenter cluster)
# @param snaphot_name name of the snapshot
############################################################################
def self.revert_snapshot(deploy_id, hostname, snapshot_name)
hid = VIClient::translate_hostname(hostname)
connection = VIClient.new(hid)
vm = connection.find_vm_template(deploy_id)
snapshot = vm.snapshot.rootSnapshotList.find {|s|
s.name == snapshot_name
}.snapshot
revert_snapshot_hash = {
:_this => snapshot
}
snapshot.RevertToSnapshot_Task(revert_snapshot_hash).wait_for_completion
end
########################################################################
# Initialize the vm monitor information
########################################################################
def monitor
@summary = @vm.summary
@state = state_to_c(@summary.runtime.powerState)
if @state != 'a'
@used_cpu = 0
@used_memory = 0
@net_rx = 0
@net_tx = 0
return
end
@used_memory = @summary.quickStats.hostMemoryUsage * 1024
host = @vm.runtime.host
cpuMhz = host.summary.hardware.cpuMhz.to_f
@used_cpu =
((@summary.quickStats.overallCpuUsage.to_f / cpuMhz) * 100).to_s
@used_cpu = sprintf('%.2f',@used_cpu).to_s
# Check for negative values
@used_memory = 0 if @used_memory.to_i < 0
@used_cpu = 0 if @used_cpu.to_i < 0
@esx_host = @vm.summary.runtime.host.name
@guest_ip = @vm.guest.ipAddress
@guest_state = @vm.guest.guestState
@vmware_tools = @vm.guest.toolsRunningStatus
@vmtools_ver = @vm.guest.toolsVersion
@vmtools_verst = @vm.guest.toolsVersionStatus
end
########################################################################
# Generates a OpenNebula IM Driver valid string with the monitor info
########################################################################
def info
return 'STATE=d' if @state == 'd'
str_info = ""
str_info << "GUEST_IP=" << @guest_ip.to_s << " " if @guest_ip
str_info << "STATE=" << @state << " "
str_info << "USEDCPU=" << @used_cpu.to_s << " "
str_info << "USEDMEMORY=" << @used_memory.to_s << " "
str_info << "NETRX=" << @net_rx.to_s << " "
str_info << "NETTX=" << @net_tx.to_s << " "
str_info << "ESX_HOST=" << @esx_host.to_s << " "
str_info << "GUEST_STATE=" << @guest_state.to_s << " "
str_info << "VMWARETOOLS_RUNNING_STATUS=" << @vmware_tools.to_s << " "
str_info << "VMWARETOOLS_VERSION=" << @vmtools_ver.to_s << " "
str_info << "VMWARETOOLS_VERSION_STATUS=" << @vmtools_verst.to_s << " "
end
########################################################################
# Generates an OpenNebula Template for this VCenterVm
#
#
########################################################################
def to_one
str = "NAME = \"#{@vm.name}\"\n"\
"CPU = \"#{@vm.config.hardware.numCPU}\"\n"\
"vCPU = \"#{@vm.config.hardware.numCPU}\"\n"\
"MEMORY = \"#{@vm.config.hardware.memoryMB}\"\n"\
"HYPERVISOR = \"vcenter\"\n"\
"PUBLIC_CLOUD = [\n"\
" TYPE =\"vcenter\",\n"\
" VM_TEMPLATE =\"#{@vm.config.uuid}\"\n"\
"]\n"\
"GRAPHICS = [\n"\
" TYPE =\"vnc\",\n"\
" LISTEN =\"0.0.0.0\"\n"\
"]\n"\
"SCHED_REQUIREMENTS=\"NAME=\\\"#{@vm.runtime.host.parent.name}\\\"\"\n"
end
private
########################################################################
# Converts the VI string state to OpenNebula state convention
########################################################################
def state_to_c(state)
case state
when 'poweredOn'
'a'
when 'suspended'
'p'
else
'd'
end
end
########################################################################
# Clone a vCenter VM Template and leaves it powered on
########################################################################
def self.clone_vm(xml_text)
xml = REXML::Document.new xml_text
pcs = xml.root.get_elements("//USER_TEMPLATE/PUBLIC_CLOUD")
raise "Cannot find VCenter element in VM template." if pcs.nil?
template = pcs.find { |t|
type = t.elements["TYPE"]
!type.nil? && type.text.downcase == "vcenter"
}
raise "Cannot find VCenter element in VM template." if template.nil?
uuid = template.elements["VM_TEMPLATE"]
raise "Cannot find VM_TEMPLATE in VCenter element." if uuid.nil?
uuid = uuid.text
vmid = xml.root.elements["/VM/ID"].text
hid = xml.root.elements["//HISTORY_RECORDS/HISTORY/HID"]
raise "Cannot find host id in deployment file history." if hid.nil?
connection = VIClient.new(hid)
vc_template = connection.find_vm_template(uuid)
relocate_spec = RbVmomi::VIM.VirtualMachineRelocateSpec(
:diskMoveType => :moveChildMostDiskBacking,
:pool => connection.resource_pool)
clone_spec = RbVmomi::VIM.VirtualMachineCloneSpec(
:location => relocate_spec,
:powerOn => true,
:template => false)
rc = vc_template.CloneVM_Task(
:folder => vc_template.parent,
:name => "one-#{vmid}",
:spec => clone_spec).wait_for_completion
vm_uuid = rc.config.uuid
vnc_port = xml.root.elements["/VM/TEMPLATE/GRAPHICS/PORT"]
vnc_listen = xml.root.elements["/VM/TEMPLATE/GRAPHICS/LISTEN"]
if !vnc_listen
vnc_listen = "0.0.0.0"
else
vnc_listen = vnc_listen.text
end
if vnc_port
spec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig =>
[{:key=>"remotedisplay.vnc.enabled", :value=>"TRUE"},
{:key=>"remotedisplay.vnc.port", :value=>vnc_port.text},
{:key=>"remotedisplay.vnc.ip", :value=>vnc_listen}])
rc.ReconfigVM_Task(:spec => spec).wait_for_completion
end
return vm_uuid
end
end
end