1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-16 22:50:10 +03:00

Merge branch 'master' into feature-3264

This commit is contained in:
Daniel Molina 2014-11-21 15:18:51 +01:00
commit 64480d6e3d
34 changed files with 522 additions and 471 deletions

View File

@ -631,7 +631,8 @@ RUBY_LIB_FILES="src/mad/ruby/ActionManager.rb \
src/vnm_mad/one_vnm.rb \
src/oca/ruby/deprecated/OpenNebula.rb \
src/oca/ruby/opennebula.rb \
src/sunstone/OpenNebulaVNC.rb"
src/sunstone/OpenNebulaVNC.rb \
src/vmm_mad/remotes/vcenter/vcenter_driver.rb"
#-------------------------------------------------------------------------------
# Ruby auth library files, to be installed under $LIB_LOCATION/ruby/opennebula
@ -784,8 +785,7 @@ VMM_EXEC_VCENTER_SCRIPTS="src/vmm_mad/remotes/vcenter/cancel \
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"
src/vmm_mad/remotes/vcenter/shutdown"
#------------------------------------------------------------------------------
# VMM Driver EC2 scripts, to be installed under $REMOTES_LOCATION/vmm/ec2

View File

@ -12,19 +12,23 @@ end
if !defined?(RUBY_VERSION) || RUBY_VERSION < '1.9.0'
$nokogiri='nokogiri --version "< 1.6.0"'
LDAP='net-ldap --version "< 0.9"'
ZENDESK_API='zendesk_api --version "< 1.5"'
else
$nokogiri='nokogiri'
DEFAULT = DEFAULT_PRE + %w{hybrid}
LDAP='net-ldap'
ZENDESK_API='zendesk_api'
end
DEFAULT = DEFAULT_PRE if !defined?(DEFAULT)
GROUPS={
:quota => [SQLITE, 'sequel'],
:sunstone => ['json', 'rack', 'sinatra', 'thin', 'zendesk_api', SQLITE],
:sunstone => ['json', 'rack', 'sinatra', 'thin', ZENDESK_API, SQLITE],
:cloud => %w{amazon-ec2 rack sinatra thin uuidtools curb json},
:hybrid => %w{softlayer_api configparser azure},
:auth_ldap => 'net-ldap',
:auth_ldap => LDAP,
:vmware => %w{builder trollop},
:oneflow => %w{sinatra json treetop parse-cron},
:ec2_hybrid => 'aws-sdk --version "= 1.33"',
@ -35,7 +39,8 @@ GROUPS={
PACKAGES=GROUPS.keys
GEM_TEST={
'net-ldap' => 'net/ldap'
LDAP => 'net/ldap',
ZENDESK_API => 'zendesk_api'
}
DISTRIBUTIONS={

View File

@ -47,7 +47,8 @@ class OpenNebula::LdapAuth
:mapping_timeout => 300,
:mapping_filename => 'server1.yaml',
:mapping_key => 'GROUP_DN',
:mapping_default => 1
:mapping_default => 1,
:attributes => [ "memberOf" ]
}.merge(options)
ops={}
@ -123,6 +124,7 @@ class OpenNebula::LdapAuth
begin
result=@ldap.search(
:base => @options[:base],
:attributes => @options[:attributes],
:filter => "#{@options[:user_field]}=#{name}")
if result && result.first
@ -146,6 +148,7 @@ class OpenNebula::LdapAuth
def is_in_group?(user, group)
result=@ldap.search(
:base => group,
:attributes => @options[:group_field],
:filter => "(#{@options[:group_field]}=#{user.first})")
if result && result.first
@ -183,7 +186,7 @@ class OpenNebula::LdapAuth
end
groups.delete(false)
groups.compact
groups.compact.uniq
end
end

View File

@ -370,7 +370,16 @@ EOT
endpoint=options[:endpoint]
end
@@client=OpenNebula::Client.new(secret, endpoint, :sync => true)
# This breaks the CLI SSL support for Ruby 1.8.7, but is necessary
# in order to do template updates, otherwise you get the broken pipe
# error (bug #3341)
if RUBY_VERSION < '1.9'
sync = false
else
sync = true
end
@@client=OpenNebula::Client.new(secret, endpoint, :sync => sync)
end
end
@ -411,8 +420,8 @@ EOT
def self.get_password
print "Password: "
system("stty", "-echo")
@@password=gets.chop
begin
@@password = STDIN.gets.chop
return @@password
ensure
system("stty", "echo")

View File

@ -16,6 +16,7 @@
require 'one_helper'
require 'one_helper/onevm_helper'
require 'rubygems'
class OneHostHelper < OpenNebulaHelper::OneHelper
TEMPLATE_XPATH = '//HOST/TEMPLATE'
@ -178,6 +179,12 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
exit(-1)
end
begin
current_version = Gem::Version.new(current_version)
rescue
STDERR.puts "VERSION file is malformed, use semantic versioning."
end
cluster_id = options[:cluster]
# Get remote_dir (implies oneadmin group)
@ -218,8 +225,17 @@ class OneHostHelper < OpenNebulaHelper::OneHelper
host_version=host['TEMPLATE/VERSION']
begin
host_version = Gem::Version.new(host_version)
rescue
end
if !options[:force]
next if host_version && host_version >= current_version
begin
next if host_version && host_version >= current_version
rescue
STDERR.puts "Error comparing versions for host #{host['NAME']}."
end
end
puts "* Adding #{host['NAME']} to upgrade"

View File

@ -162,10 +162,20 @@ class OneUserHelper < OpenNebulaHelper::OneHelper
# Authenticate with oned using the token/passwd and set/generate the
# authentication token for the user
#-----------------------------------------------------------------------
# This breaks the CLI SSL support for Ruby 1.8.7, but is necessary
# in order to do template updates, otherwise you get the broken pipe
# error (bug #3341)
if RUBY_VERSION < '1.9'
sync = false
else
sync = true
end
token = auth.login_token(username, options[:time])
login_client = OpenNebula::Client.new("#{username}:#{token}",
nil,
:sync => true)
:sync => sync)
user = OpenNebula::User.new(User.build_xml, login_client)

View File

@ -419,13 +419,13 @@ class OneVMHelper < OpenNebulaHelper::OneHelper
case hybridvisor
when "vcenter"
nic.IP = vm_tmplt['GUEST_IP'] if vm_tmplt['GUEST_IP']
nic["IP"] = vm_tmplt['GUEST_IP'] if vm_tmplt['GUEST_IP']
when "ec2"
nic.IP = vm_tmplt['IP_ADDRESS'] if vm_tmplt['IP_ADDRESS']
nic["IP"] = vm_tmplt['IP_ADDRESS'] if vm_tmplt['IP_ADDRESS']
when "azure"
nic.IP = vm_tmplt['IPADDRESS'] if vm_tmplt['IPADDRESS']
nic["IP"] = vm_tmplt['IPADDRESS'] if vm_tmplt['IPADDRESS']
when "softlayer"
nic.IP = vm_tmplt['PRIMARYIPADDRESS'] if vm_tmplt['PRIMARYIPADDRESS']
nic["IP"] = vm_tmplt['PRIMARYIPADDRESS'] if vm_tmplt['PRIMARYIPADDRESS']
else
isHybrid = false
end

View File

@ -50,7 +50,7 @@ module EC2CloudAuth
digest_generator = OpenSSL::Digest::Digest.new(digest)
digest = OpenSSL::HMAC.digest(digest_generator, secret_key, req_desc)
b64sig = Base64.b64encode(digest)
b64sig = Base64.encode64(digest)
return b64sig.strip
end

View File

@ -94,11 +94,11 @@
# Script to associate a public IP with a private IP
# - arguments: elastic_ip private_ip vnet_template(base64_encoded)
:associate_script: /usr/bin/false
:associate_script: false
# Script to disassociate a public IP
# - arguments: elastic_ip
:disassociate_script: /usr/bin/false
:disassociate_script: false
#############################################################
# EBS

View File

@ -17,7 +17,7 @@ DISK = [ IMAGE_ID = <%= erb_vm_info[:img_id] %> ]
NIC=[NETWORK_ID=<EC2-VNET-ID>]
IMAGE_ID = <%= erb_vm_info[:ec2_img_id] %>
INSTANCE_TYPE = <%= erb_vm_info[:instance_type ]%>
EC2_INSTANCE_TYPE = <%= erb_vm_info[:instance_type ]%>
<% if erb_vm_info[:user_data] && erb_vm_info[:public_key] %>
CONTEXT = [ EC2_USER_DATA="<%= erb_vm_info[:user_data] %>", EC2_PUBLIC_KEY="<%= erb_vm_info[:public_key] %>", EC2_KEYNAME ="<%= erb_vm_info[:key_name] %>" ]

View File

@ -31,7 +31,7 @@
<keyName><%= vm['TEMPLATE/CONTEXT/EC2_KEYNAME'] %></keyName>
<% end %>
<productCodes/>
<instanceType><%= vm['USER_TEMPLATE/INSTANCE_TYPE'] %></instanceType>
<instanceType><%= vm['USER_TEMPLATE/EC2_INSTANCE_TYPE'] %></instanceType>
<%= render_launch_time(vm) %>
<placement>
<availabilityZone>default</availabilityZone>

View File

@ -24,7 +24,7 @@
<% else %>
<keyName><%= vm['TEMPLATE/CONTEXT/EC2_KEYNAME'] %></keyName>
<% end %>
<instanceType><%= vm['USER_TEMPLATE/INSTANCE_TYPE'] %></instanceType>
<instanceType><%= vm['USER_TEMPLATE/EC2_INSTANCE_TYPE'] %></instanceType>
<%= render_launch_time(vm) %>
<placement>
<availabilityZone>default</availabilityZone>

View File

@ -24,6 +24,7 @@ else
RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" if !defined?(RUBY_LIB_LOCATION)
end
$: << RUBY_LIB_LOCATION
$: << "../../vmm/vcenter/"
require 'vcenter_driver'

View File

@ -1356,7 +1356,7 @@ void LifeCycleManager::monitor_poweron_action(int vid)
vm->set_running_stime(the_time);
vm->set_last_poll(0);
vm->set_last_poll(the_time);
vmpool->update_history(vm);

View File

@ -236,7 +236,7 @@ module OpenNebula
return Error.new('ID not defined') if !@pe_id
rtmpl = "SIZE = #{rsize}\n"
rtmpl << "NAME = #{rname}\n" if !rname.nil?
rtmpl << "NAME = \"#{rname}\"\n" if !rname.nil?
rtmpl << "AR_ID = #{ar_id}\n" if !ar_id.nil?
rtmpl << "NETWORK_ID = #{vnet}\n" if !vnet.nil?

View File

@ -91,7 +91,7 @@ void RequestManagerDelete::request_execute(xmlrpc_c::paramList const& paramList,
if ( rc != 0 )
{
failure_response(INTERNAL,
failure_response(ACTION,
request_error("Cannot delete "+object_name(auth_object),error_msg),
att);
return;

View File

@ -35,15 +35,15 @@ tabs:
Dashboard.refresh: false
Sunstone.toggle_top: false
widgets_three_per_row:
- storage
- users
- network
# - storage
# - network
widgets_two_per_row:
# - user_quotas
# - group_quotas
widgets_one_per_row:
- vms
- hosts
- users
widgets_one_footer:
# - accounting
system-tab:
@ -205,6 +205,7 @@ tabs:
input_output: true
context: true
scheduling: true
hybrid: true
other: true
images-tab:
panel_tabs:

File diff suppressed because one or more lines are too long

View File

@ -1807,7 +1807,7 @@ var OpenNebula = {
OpenNebula.Role.path);
},
"update" : function(params){
request = OpenNebula.Helper.request(OpenNebula.Role.resource, "update", params.data.id);
var request = OpenNebula.Helper.request(OpenNebula.Role.resource, "update", params.data.id);
$.ajax({
url: OpenNebula.Role.path + "/" + params.data.id,
@ -1815,10 +1815,10 @@ var OpenNebula = {
dataType: "json",
data: JSON.stringify(params.data.extra_param),
success: function(response){
return roleCallback(request, response);
return params.success ? params.success(request, response) : null;
},
error: function(response){
return onError(request, OpenNebula.Error(response));
return params.error ? params.error(request, OpenNebula.Error(res)) : null;
}
});
}

View File

@ -674,6 +674,9 @@ function popUpCreateAclDialog(){
insertSelectOptions('div#belonging_to', dialog, "Group", null, true);
insertSelectOptions('#in_cluster',dialog, "Cluster", null, true);
// Delete cluster -1 option
$('#in_cluster select option[value="-1"]',dialog).remove();
insertSelectOptions('div#zones_applies', dialog, "Zone", "*", false,
'<option value="*">'+tr("All")+'</option>');

View File

@ -74,13 +74,9 @@ function setupCreateClusterDialog(){
dialog.addClass("reveal-modal large max-height").attr("data-reveal", "");
var opts = {
multiple_choice: true
};
setupHostTableSelect(dialog, "cluster_wizard_hosts", opts);
setupVNetTableSelect(dialog, "cluster_wizard_vnets", opts);
setupDatastoreTableSelect(dialog, "cluster_wizard_datastores", opts);
setupHostTableSelect(dialog, "cluster_wizard_hosts", {multiple_choice: true});
setupVNetTableSelect(dialog, "cluster_wizard_vnets", {multiple_choice: true});
setupDatastoreTableSelect(dialog, "cluster_wizard_datastores", {multiple_choice: true});
// Handle the Create button
$('#create_cluster_submit').click(function(){

View File

@ -127,24 +127,12 @@ var create_datastore_tmpl =
'</label>\
<input type="text" name="safe_dirs" id="safe_dirs" />\
</div>\
</div>\
<div class="row">\
<div class="large-12 columns">\
<label for="restricted_dirs">' + tr("Restricted Directories") +
'<span class="tip">'+tr("Paths that can not be used to register images. A space separated list of paths. This will prevent users registering important files as VM images and accessing them thourgh their VMs. OpenNebula will automatically add its configuration directories: /var/lib/one, /etc/one and oneadmin's home ($HOME).")+'</span>'+
'</label>\
<input type="text" name="restricted_dirs" id="restricted_dirs" />\
</div>\
</div>\
<div class="row">\
<div class="large-12 columns">\
<label for="bridge_list">' + tr("Host Bridge List") +
'<span class="tip">'+tr("Space separated list of Server names or IPs where OpenNebula will be staging the new images into. This server will act as the entry point for new inmages in the datastore.")+'</span>'+
'</label>\
<input type="text" name="bridge_list" id="bridge_list" />\
</div>\
</div>\
<div class="row">\
<div class="large-6 columns">\
<label for="base_path">' + tr("Base Path") +
'<span class="tip">'+tr("When needed, the front-end will access the datastores using BASE_PATH (defaults to /var/lib/one/datastores).")+'</span>'+
@ -152,18 +140,10 @@ var create_datastore_tmpl =
<input type="text" name="base_path" id="base_path" />\
</div>\
<div class="large-6 columns">\
<input id="ds_use_ssh" type="checkbox" name="ds_use_ssh" value="YES" /><label for="ds_use_ssh">' + tr("Use SSH for Datastore Manager") + '</label>\
</div>\
<div class="large-6 columns">\
<input id="tm_use_ssh" type="checkbox" name="tm_use_ssh" value="YES" /><label class="inline" for="tm_use_ssh">' + tr("Use SSH for Transfer Manager") + '</label>\
</div>\
<div class="large-6 columns">\
<label for="base_iqn">' + tr("Base IQN") + '</label>\
<input type="text" name="base_iqn" id="base_iqn" />\
</div>\
<div class="large-6 columns">\
<label for="vg_name">' + tr("Volume Group Name") + '</label>\
<input type="text" name="vg_name" id="vg_name" />\
<label for="limit_transfer_bw">' + tr("Transfer BW Limit") +
'<span class="tip">'+tr("Specify the maximum transfer rate in bytes/second when downloading images from a http/https URL. Suffixes K, M or G can be used.")+'</span>'+
'</label>\
<input type="text" name="limit_transfer_bw" id="limit_transfer_bw" />\
</div>\
<div class="large-6 columns">\
<label for="limit_mb">' + tr("Limit") +
@ -171,36 +151,76 @@ var create_datastore_tmpl =
'</label>\
<input type="text" name="limit_mb" id="limit_mb" />\
</div>\
</div>\
<div class="large-6 columns">\
<label for="gluster_host">' + tr("Gluster Host") +
'<span class="tip">'+tr("Host and port of one (and only one) Gluster server (host:port)")+'</span>'+
<div class="large-12 columns">\
<input id="no_decompress" type="checkbox" name="no_decompress" value="YES" /><label for="no_decompress">' + tr("Do not try to untar or decompress") + '</label>\
</div>\
<div class="large-12 columns">\
<input id="datastore_capacity_check" type="checkbox" name="datastore_capacity_check" value="YES" /><label for="datastore_capacity_check">' + tr("Check available capacity of the datastore before creating a new image") + '</label>\
</div>\
<div class="large-12 columns">\
<label for="bridge_list">' + tr("Host Bridge List") +
'<span class="tip">'+tr("Space separated list of Server names or IPs where OpenNebula will be staging the new images into. This server will act as the entry point for new inmages in the datastore.")+'</span>'+
'</label>\
<input type="text" name="gluster_host" id="gluster_host" />\
</div>\
<div class="large-6 columns">\
<label for="gluster_volume">' + tr("Gluster Volume") +
'<span class="tip">'+tr("Gluster volume to use for the datastore")+'</span>'+
'</label>\
<input type="text" name="gluster_volume" id="gluster_volume" />\
</div>\
<div class="large-6 columns">\
<label for="pool_name">' + tr("Pool Name") +
'<span class="tip">'+tr("The OpenNebula Ceph pool name. Defaults to \"one\" (this pool must exist before using the drivers).")+'</span>'+
'</label>\
<input type="text" name="pool_name" id="pool_name" />\
</div>\
<div class="large-6 columns">\
<label for="ceph_host">' + tr("Ceph Host") +
'<span class="tip">'+tr("Space-separated list of Ceph monitors. Example: host1 host2:port2 host3 host4:port4 (if no port is specified, the default one is chosen) (Required for Libvirt 1.x when cephx is enabled).")+'</span>'+
'</label>\
<input type="text" name="ceph_host" id="ceph_host" />\
</div>\
<div class="large-6 columns">\
<label for="ceph_secret">' + tr("Ceph Secret") +
'<span class="tip">'+tr("A generated UUID for a LibVirt secret (to hold the CephX authentication key in Libvirt on each hypervisor). This should be generated when creating the Ceph datastore in OpenNebula. (Required for Libvirt 1.x when cephx is enabled).")+'</span>'+
'</label>\
<input type="text" name="ceph_secret" id="ceph_secret" />\
<input type="text" name="bridge_list" id="bridge_list" />\
</div>\
<div class="large-6 columns">\
<label for="ds_tmp_dir">' + tr("DS Tmp Dir") +
'<span class="tip">'+tr("Path in the OpenNebula front-end to be used as a buffer to stage in files in vmfs datastores.")+'</span>'+
'</label>\
<input type="text" name="ds_tmp_dir" id="ds_tmp_dir" />\
</div>\
<div class="large-6 columns">\
<label for="vg_name">' + tr("Volume Group Name") + '</label>\
<input type="text" name="vg_name" id="vg_name" />\
</div>\
<div class="large-6 columns">\
<label for="gluster_host">' + tr("Gluster Host") +
'<span class="tip">'+tr("Host and port of one (and only one) Gluster server (host:port)")+'</span>'+
'</label>\
<input type="text" name="gluster_host" id="gluster_host" />\
</div>\
<div class="large-6 columns">\
<label for="gluster_volume">' + tr("Gluster Volume") +
'<span class="tip">'+tr("Gluster volume to use for the datastore")+'</span>'+
'</label>\
<input type="text" name="gluster_volume" id="gluster_volume" />\
</div>\
<div class="large-6 columns">\
<label for="pool_name">' + tr("Pool Name") +
'<span class="tip">'+tr("The OpenNebula Ceph pool name. Defaults to 'one' (this pool must exist before using the drivers).")+'</span>'+
'</label>\
<input type="text" name="pool_name" id="pool_name" />\
</div>\
<div class="large-6 columns">\
<label for="ceph_host">' + tr("Ceph Host") +
'<span class="tip">'+tr("Space-separated list of Ceph monitors. Example: host1 host2:port2 host3 host4:port4 (if no port is specified, the default one is chosen) (Required for Libvirt 1.x when cephx is enabled).")+'</span>'+
'</label>\
<input type="text" name="ceph_host" id="ceph_host" />\
</div>\
<div class="large-6 columns">\
<label for="ceph_user">' + tr("Ceph User") +
'<span class="tip">'+tr("The OpenNebula Ceph user name. If set it is used by RBD commands. This ceph user must exist before using the drivers. Required for Libvirt 1.x when cephx is enabled .")+'</span>'+
'</label>\
<input type="text" name="ceph_user" id="ceph_user" />\
</div>\
<div class="large-6 columns">\
<label for="ceph_secret">' + tr("Ceph Secret") +
'<span class="tip">'+tr("A generated UUID for a LibVirt secret (to hold the CephX authentication key in Libvirt on each hypervisor). This should be generated when creating the Ceph datastore in OpenNebula. (Required for Libvirt 1.x when cephx is enabled).")+'</span>'+
'</label>\
<input type="text" name="ceph_secret" id="ceph_secret" />\
</div>\
<div class="large-6 columns">\
<label for="rbd_format">' + tr("RBD Format") +
'<span class="tip">'+tr("By default RBD Format 2 will be used. If RBD_FORMAT=2 is specified then when instantiating non-persistent images the Ceph driver will perform rbd snap instead of rbd copy.")+'</span>'+
'</label>\
<input type="text" name="rbd_format" id="rbd_format" />\
</div>\
<div class="large-6 columns">\
<label for="staging_dir">' + tr("Staging Dir") +
'<span class="tip">'+tr("Default path for image operations in the OpenNebula Ceph frontend.")+'</span>'+
'</label>\
<input type="text" name="staging_dir" id="staging_dir" />\
</div>\
</div>\
<div class="reveal-footer">\
<div class="form_buttons">\
@ -788,20 +808,23 @@ function hide_all(context)
{
// Hide all the options that depends on datastore type
// and reset the selects
$('label[for="ds_use_ssh"],input#ds_use_ssh',context).hide();
$('label[for="tm_use_ssh"],input#tm_use_ssh',context).hide();
$('input#image_ds_type').attr('checked', 'true');
$('input[name=ds_type]').removeAttr('disabled', 'disabled');
$('label[for="bridge_list"],input#bridge_list',context).parent().parent().hide();
$('label[for="base_iqn"],input#base_iqn',context).hide();
$('label[for="bridge_list"],input#bridge_list',context).parent().hide();
$('label[for="ds_tmp_dir"],input#ds_tmp_dir',context).parent().hide();
$('label[for="vg_name"],input#vg_name',context).hide();
$('label[for="gluster_host"],input#gluster_host',context).parent().hide();
$('label[for="gluster_volume"],input#gluster_volume',context).parent().hide();
$('label[for="pool_name"],input#pool_name',context).parent().hide();
$('label[for="ceph_host"],input#ceph_host',context).parent().hide();
$('label[for="ceph_secret"],input#ceph_secret',context).parent().hide();
$('label[for="ceph_user"],input#ceph_user',context).parent().hide();
$('label[for="rbd_format"],input#rbd_format',context).parent().hide();
$('label[for="staging_dir"],input#staging_dir',context).parent().hide();
$('label[for="limit_transfer_bw"],input#limit_transfer_bw',context).parent().hide();
$('label[for="no_decompress"],input#no_decompress',context).parent().hide();
$('select#ds_mad').removeAttr('disabled');
$('select#tm_mad').removeAttr('disabled');
$('select#tm_mad').children('option').each(function() {
@ -890,13 +913,16 @@ function setupCreateDatastoreDialog(){
var tm_mad = $('#tm_mad',context).val();
tm_mad = tm_mad == "custom" ? $('input[name="ds_tab_custom_tm_mad"]').val() : tm_mad;
var type = $('#disk_type',context).val();
var safe_dirs = $('#safe_dirs',context).val();
var base_path = $('#base_path',context).val();
var restricted_dirs = $('#restricted_dirs',context).val();
var limit_transfer_bw = $('#limit_transfer_bw',context).val();
var datastore_capacity_check = $('#datastore_capacity_check',context).is(':checked');
var no_decompress = $('#no_decompress',context).is(':checked');
var bridge_list = $('#bridge_list',context).val();
var ds_use_ssh = $('#ds_use_ssh',context).is(':checked');
var tm_use_ssh = $('#tm_use_ssh',context).is(':checked');
var base_iqn = $('#base_iqn',context).val();
var ds_tmp_dir = $('#ds_tmp_dir',context).val();
var vg_name = $('#vg_name',context).val();
var limit_mb = $('#limit_mb',context).val();
var gluster_host = $('#gluster_host',context).val();
@ -904,6 +930,9 @@ function setupCreateDatastoreDialog(){
var pool_name = $('#pool_name',context).val();
var ceph_host = $('#ceph_host',context).val();
var ceph_secret = $('#ceph_secret',context).val();
var ceph_user = $('#ceph_user',context).val();
var rbd_format = $('#rbd_format',context).val();
var staging_dir = $('#staging_dir',context).val();
if (!name){
@ -935,17 +964,20 @@ function setupCreateDatastoreDialog(){
if (restricted_dirs)
ds_obj.datastore.restricted_dirs = restricted_dirs;
if (limit_transfer_bw)
ds_obj.datastore.limit_transfer_bw = limit_transfer_bw;
if (no_decompress)
ds_obj.datastore.no_decompress = "YES";
if (datastore_capacity_check)
ds_obj.datastore.datastore_capacity_check = "YES";
if (bridge_list)
ds_obj.datastore.bridge_list = bridge_list;
if (ds_use_ssh)
ds_obj.datastore.ds_use_ssh = "YES";
if (tm_use_ssh)
ds_obj.datastore.tm_use_ssh = "YES";
if (base_iqn)
ds_obj.datastore.base_iqn = base_iqn;
if (ds_tmp_dir)
ds_obj.datastore.ds_tmp_dir = ds_tmp_dir;
if (vg_name)
ds_obj.datastore.vg_name = vg_name;
@ -957,7 +989,7 @@ function setupCreateDatastoreDialog(){
ds_obj.datastore.gluster_host = gluster_host;
if (gluster_volume)
ds_obj.datastore.gluster_host = gluster_volume;
ds_obj.datastore.gluster_volume = gluster_volume;
if (pool_name)
ds_obj.datastore.pool_name = pool_name;
@ -968,9 +1000,14 @@ function setupCreateDatastoreDialog(){
if (ceph_secret)
ds_obj.datastore.ceph_secret = ceph_secret;
// Sanitize dialog
$('#ds_use_ssh').prop('checked', false);
$('#tm_use_ssh').prop('checked', false);
if (ceph_user)
ds_obj.datastore.ceph_user = ceph_user;
if (rbd_format)
ds_obj.datastore.rbd_format = rbd_format;
if (staging_dir)
ds_obj.datastore.staging_dir = staging_dir;
Sunstone.runAction("Datastore.create",ds_obj);
return false;
@ -1033,6 +1070,9 @@ function select_filesystem(){
});
$('select#disk_type').val('file');
$('select#disk_type').attr('disabled', 'disabled');
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
$('input#safe_dirs').removeAttr('disabled');
$('select#disk_type').removeAttr('disabled');
$('input#base_path').removeAttr('disabled');
@ -1041,13 +1081,15 @@ function select_filesystem(){
}
function select_vmware_vmfs(){
$('label[for="bridge_list"],input#bridge_list').parent().parent().fadeIn();
$('label[for="ds_use_ssh"],input#ds_use_ssh').fadeIn();
$('label[for="tm_use_ssh"],input#tm_use_ssh').fadeIn();
$('label[for="bridge_list"],input#bridge_list').parent().fadeIn();
$('label[for="ds_tmp_dir"],input#ds_tmp_dir').parent().fadeIn();
$('select#ds_mad').val('vmfs');
$('select#ds_mad').attr('disabled', 'disabled');
$('select#tm_mad').val('vmfs');
$('select#tm_mad').attr('disabled', 'disabled');
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
$('select#disk_type').val('file');
$('select#disk_type').attr('disabled', 'disabled');
$('input#safe_dirs').removeAttr('disabled');
@ -1063,10 +1105,16 @@ function select_ceph(){
$('select#ds_mad').attr('disabled', 'disabled');
$('select#tm_mad').val('ceph');
$('select#tm_mad').attr('disabled', 'disabled');
$('label[for="bridge_list"],input#bridge_list').parent().parent().fadeIn();
$('label[for="bridge_list"],input#bridge_list').parent().fadeIn();
$('label[for="pool_name"],input#pool_name').parent().fadeIn();
$('label[for="ceph_host"],input#ceph_host').parent().fadeIn();
$('label[for="ceph_secret"],input#ceph_secret').parent().fadeIn();
$('label[for="ceph_user"],input#ceph_user').parent().fadeIn();
$('label[for="rbd_format"],input#rbd_format').parent().fadeIn();
$('label[for="staging_dir"],input#staging_dir').parent().fadeIn();
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
$('select#disk_type').val('RBD');
$('select#disk_type').attr('disabled', 'disabled');
$('input#safe_dirs').removeAttr('disabled');
@ -1082,8 +1130,11 @@ function select_block_lvm(){
$('select#tm_mad').attr('disabled', 'disabled');
$('input#image_ds_type').attr('checked', 'true');
$('input[name=ds_type]').attr('disabled', 'disabled');
$('label[for="bridge_list"],input#bridge_list').parent().parent().fadeIn();
$('label[for="bridge_list"],input#bridge_list').parent().fadeIn();
$('label[for="vg_name"],input#vg_name').fadeIn();
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
$('select#disk_type').val('block');
$('select#disk_type').attr('disabled', 'disabled');
$('input#safe_dirs').removeAttr('disabled');
@ -1099,6 +1150,9 @@ function select_fs_lvm(){
$('select#tm_mad').attr('disabled', 'disabled');
$('input#image_ds_type').attr('checked', 'true');
$('input[name=ds_type]').attr('disabled', 'disabled');
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
$('select#disk_type').val('block');
$('select#disk_type').attr('disabled', 'disabled');
$('input#safe_dirs').removeAttr('disabled');
@ -1126,6 +1180,9 @@ function select_gluster(){
$('select#disk_type').attr('disabled', 'disabled');
$('label[for="gluster_host"],input#gluster_host').parent().fadeIn();
$('label[for="gluster_volume"],input#gluster_volume').parent().fadeIn();
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
$('input#safe_dirs').removeAttr('disabled');
$('input#base_path').removeAttr('disabled');
$('input#limit_mb').removeAttr('disabled');
@ -1141,6 +1198,9 @@ function select_devices(){
$('input[name=ds_type]').attr('disabled', 'disabled');
$('select#disk_type').val('block');
$('select#disk_type').attr('disabled', 'disabled');
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().hide();
$('label[for="no_decompress"],input#no_decompress').parent().hide();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().hide();
$('input#safe_dirs').attr('disabled', 'disabled');
$('input#base_path').attr('disabled', 'disabled');
$('input#limit_mb').attr('disabled', 'disabled');
@ -1156,6 +1216,9 @@ function select_custom(){
$('input#base_path').removeAttr('disabled');
$('input#limit_mb').removeAttr('disabled');
$('input#restricted_dirs').removeAttr('disabled');
$('label[for="limit_transfer_bw"],input#limit_transfer_bw').parent().fadeIn();
$('label[for="no_decompress"],input#no_decompress').parent().fadeIn();
$('label[for="datastore_capacity_check"],input#datastore_capacity_check').parent().fadeIn();
}
function popUpCreateDatastoreDialog(){

View File

@ -210,6 +210,7 @@ var host_actions = {
updateHostElement(request, response);
if (Sunstone.rightInfoVisible($("#hosts-tab"))) {
updateHostInfo(request, response);
$(".right-info-tabs > dd.active > a", "#hosts-tab").trigger("click");
}
},
error: onError
@ -1042,8 +1043,10 @@ function updateHostInfo(request,host){
//pop up panel while we retrieve the graphs
Sunstone.runAction("Host.monitor",host_info.ID,
{monitor_resources : "HOST_SHARE/CPU_USAGE,HOST_SHARE/USED_CPU,HOST_SHARE/MAX_CPU,HOST_SHARE/MEM_USAGE,HOST_SHARE/USED_MEM,HOST_SHARE/MAX_MEM"});
$("[href='#host_monitoring_tab']").on("click", function(){
Sunstone.runAction("Host.monitor",host_info.ID,
{monitor_resources : "HOST_SHARE/CPU_USAGE,HOST_SHARE/USED_CPU,HOST_SHARE/MAX_CPU,HOST_SHARE/MEM_USAGE,HOST_SHARE/USED_MEM,HOST_SHARE/MAX_MEM"});
});
}
//Prepares the host creation dialog

View File

@ -1390,7 +1390,12 @@ function initialize_create_service_template_dialog(dialog){
}).on('valid', function() {
if ($('#create_service_template_form_advanced',dialog).attr("action") == "create") {
var json_template = $("#template", this).val();
Sunstone.runAction("ServiceTemplate.create", JSON.parse(json_template) );
try {
Sunstone.runAction("ServiceTemplate.create", JSON.parse(json_template) );
} catch(e) {
popFormDialog("create_service_template_form", $("#oneflow-templates"));
notifyError(e);
}
return false;
} else if ($('#create_service_template_form_advanced',dialog).attr("action") == "update") {
var json_template = $("#template", this).val();
@ -1881,6 +1886,7 @@ function setupInstantiateServiceTemplateDialog(){
}
}
$instantiate_service_template_dialog.empty();
$instantiate_service_template_dialog.foundation('reveal', 'close')
return false;
});

View File

@ -1785,9 +1785,9 @@ var povision_actions = {
Sunstone.runAction("Provision.User.set_quota", [response.USER.ID], {
"VM" : {
"VOLATILE_SIZE":"-1",
"VMS": $("#provision_rvms_quota_input").val()||QUOTA_LIMIT_UNLIMITED,
"MEMORY": $("#provision_memory_quota_input").val()||QUOTA_LIMIT_UNLIMITED,
"CPU": $("#provision_cpu_quota_input").val()||QUOTA_LIMIT_UNLIMITED}
"VMS": $(".provision_rvms_quota_input").val()||QUOTA_LIMIT_UNLIMITED,
"MEMORY": $(".provision_memory_quota_input").val()||QUOTA_LIMIT_UNLIMITED,
"CPU": $(".provision_cpu_quota_input").val()||QUOTA_LIMIT_UNLIMITED}
});
},
error: onError
@ -2407,7 +2407,7 @@ function generate_provision_network_table(context, nic, vnet_attr){
update_provision_networks_datatable(provision_networks_datatable);
}
function generate_provision_network_accordion(context){
function generate_provision_network_accordion(context, hide_add_button){
context.off();
context.html(
'<br>'+
@ -2428,7 +2428,7 @@ function generate_provision_network_accordion(context){
'<dl class="accordion provision_nic_accordion" data-accordion="provision_accordion_'+provision_nic_accordion_id+'">'+
'</dl>'+
'<br>'+
'<a class="button large-12 medium radius secondary provision_add_network_interface" style="padding: 1rem; color: #555">'+
'<a class="button large-12 medium radius secondary provision_add_network_interface" style="padding: 1rem; color: #555; ' + (hide_add_button ? 'display:none;' : '') + '">'+
tr("Add another Network Interface")+
'</a>'+
'</div>'+
@ -2749,41 +2749,16 @@ function show_provision_user_info_callback(request, response) {
var info = response.USER;
var default_user_quotas = Quotas.default_quotas(info.DEFAULT_USER_QUOTAS);
var vms_quota = Quotas.vms(info, default_user_quotas);
var cpu_quota = Quotas.cpu(info, default_user_quotas);
var memory_quota = Quotas.memory(info, default_user_quotas);
var volatile_size_quota = Quotas.volatile_size(info, default_user_quotas);
var image_quota = Quotas.image(info, default_user_quotas);
var network_quota = Quotas.network(info, default_user_quotas);
var datastore_quota = Quotas.datastore(info, default_user_quotas);
var quotas_html;
if (vms_quota || cpu_quota || memory_quota || volatile_size_quota || image_quota || network_quota || datastore_quota) {
quotas_html = '<div class="large-6 columns">' + vms_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + cpu_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + memory_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + volatile_size_quota+ '</div>';
quotas_html += '<div class="large-6 columns">' + image_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + network_quota + '</div>';
quotas_html += '<div class="large-12 columns">' + datastore_quota + '</div>';
} else {
quotas_html = '<div class="row">'+
'<div class="large-8 large-centered columns">'+
'<div class="text-center">'+
'<span class="fa-stack fa-5x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-align-left fa-stack-1x fa-inverse"></i>'+
'</span>'+
'<br>'+
'<p style="font-size: 18px; color: #999">'+
tr("There are no quotas defined")+
'</p>'+
'</div>'+
'</div>'+
'</div>';
}
var quotas_tab_html = initQuotasPanel(info, default_user_quotas,
"#provision_user_info_quotas_div", false);
$("#provision_user_info_quotas_div").html(quotas_html);
$("#provision_user_info_quotas_div").html(quotas_tab_html);
setupQuotasPanel(info,
"#provision_user_info_quotas_div",
false,
"User");
var ssh_key = info.TEMPLATE.SSH_PUBLIC_KEY;
if (ssh_key && ssh_key.length) {
@ -2818,41 +2793,16 @@ function show_provision_group_info_callback(request, response) {
var context = $("#provision_manage_vdc");
var default_group_quotas = Quotas.default_quotas(info.DEFAULT_GROUP_QUOTAS);
var vms_quota = Quotas.vms(info, default_group_quotas);
var cpu_quota = Quotas.cpu(info, default_group_quotas);
var memory_quota = Quotas.memory(info, default_group_quotas);
var volatile_size_quota = Quotas.volatile_size(info, default_group_quotas);
var image_quota = Quotas.image(info, default_group_quotas);
var network_quota = Quotas.network(info, default_group_quotas);
var datastore_quota = Quotas.datastore(info, default_group_quotas);
var quotas_html;
if (vms_quota || cpu_quota || memory_quota || volatile_size_quota || image_quota || network_quota || datastore_quota) {
quotas_html = '<div class="large-6 columns">' + vms_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + cpu_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + memory_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + volatile_size_quota+ '</div>';
quotas_html += '<div class="large-6 columns">' + image_quota + '</div>';
quotas_html += '<div class="large-6 columns">' + network_quota + '</div>';
quotas_html += '<div class="large-12 columns">' + datastore_quota + '</div>';
} else {
quotas_html = '<div class="row">'+
'<div class="large-8 large-centered columns">'+
'<div class="text-center">'+
'<span class="fa-stack fa-5x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-align-left fa-stack-1x fa-inverse"></i>'+
'</span>'+
'<br>'+
'<p style="font-size: 18px; color: #999">'+
tr("There are no quotas defined")+
'</p>'+
'</div>'+
'</div>'+
'</div>';
}
var quotas_tab_html = initQuotasPanel(info, default_group_quotas,
"#provision_vdc_quotas_div", false);
$("#provision_vdc_quotas_div").html(quotas_html);
$("#provision_vdc_quotas_div").html(quotas_tab_html);
setupQuotasPanel(info,
"#provision_vdc_quotas_div",
false,
"Group");
accountingGraphs(
$("#provision_info_vdc_group_acct", context),
@ -2869,6 +2819,7 @@ function show_provision_group_info_callback(request, response) {
}
function show_provision_create_vm() {
OpenNebula.Helper.clear_cache("VMTEMPLATE");
update_provision_templates_datatable(provision_system_templates_datatable);
provision_system_templates_datatable.fnFilter("^-$", 2, true, false)
@ -3423,23 +3374,7 @@ function get_provision_disk_image(data) {
}
function get_provision_ips(data) {
var nics = []
if ($.isArray(data.TEMPLATE.NIC))
nics = data.TEMPLATE.NIC
else if (!$.isEmptyObject(data.TEMPLATE.NIC))
nics = [data.TEMPLATE.NIC]
if (nics.length > 0) {
var ips = [];
$.each(nics, function(index, nic){
if (nic.IP)
ips.push(nic.IP);
})
return '<i class="fa fa-fw fa-lg fa-globe"></i> ' + ips.join(', ');
} else {
return '<i class="fa fa-fw fa-lg fa-globe"></i> -';
}
return '<i class="fa fa-fw fa-lg fa-globe"></i> ' + ip_str(data, " - ");
}
// @params
@ -4514,7 +4449,7 @@ function generate_provision_templates_list(context, opts) {
}
function setup_info_flow(context) {
function update_provision_flow_info(flow_id, context) {
function update_provision_flow_info(flow_id, context, role_id) {
$(".provision_info_flow_name", context).text("");
$(".provision_info_flow", context).css('visibility', 'hidden');
$(".provision_info_flow_loading", context).fadeIn();
@ -4631,6 +4566,9 @@ function setup_info_flow(context) {
'</li>').appendTo($(".provision_roles_ul", context));
$(".provision_role_ul", li).data("role", role);
if (role_id && role_id == role.name) {
$(".provision_role_vms_button", li).trigger("click");
}
});
}
@ -4657,9 +4595,10 @@ function setup_info_flow(context) {
'</div>');
var role = $(this).closest(".provision_role_ul").data('role');
$(".provision_info_flow", context).data("role_id", role.name);
var vms = []
if (role.nodes.length > 0) {
if (role.nodes && role.nodes.length > 0) {
$.each(role.nodes, function(index, node){
vms.push(node.vm_info);
})
@ -4670,9 +4609,9 @@ function setup_info_flow(context) {
{
title: role.name + ' ' + tr("VMs"),
active: true,
refresh: true,
refresh: false,
create: false,
filter: true,
filter: false,
data: vms
});
})
@ -4759,7 +4698,7 @@ function setup_info_flow(context) {
},
success: function(request, response){
OpenNebula.Helper.clear_cache("SERVICE");
update_provision_flow_info(flow_id, context);
$(".provision_refresh_info", context).trigger("click");
},
error: onError
})
@ -4854,7 +4793,8 @@ function setup_info_flow(context) {
context.on("click", ".provision_refresh_info", function(){
var flow_id = $(".provision_info_flow", context).attr("flow_id");
update_provision_flow_info(flow_id, context);
var role_id = $(".provision_info_flow", context).data("role_id");
update_provision_flow_info(flow_id, context, role_id);
//$(".provision_flows_list_refresh_button", $(".provision_flows_list_section")).trigger("click");
return false;
});
@ -5991,6 +5931,59 @@ $(document).ready(function(){
// Create VM
//
function appendTemplateCard(aData, tableID) {
var data = aData.VMTEMPLATE;
var logo;
if (data.TEMPLATE.LOGO) {
logo = '<span class="provision-logo" href="#">'+
'<img src="'+data.TEMPLATE.LOGO+'">'+
'</span>';
} else {
logo = '<span style="color: #bfbfbf; font-size: 60px;">'+
'<i class="fa fa-fw fa-file-text-o"/>'+
'</span>';
}
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
'<li style="height: 85px" class="provision-bullet-item">'+
logo +
'</li>'+
'<li class="provision-description">'+
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>').appendTo($("#"+tableID+'_ul'));
$(".provision-pricing-table", li).data("opennebula", aData);
}
function initializeTemplateCards(context, tableID) {
// create a thumbs container if it doesn't exist. put it in the dataTables_scrollbody div
if (context.$('tr', {"filter": "applied"} ).length == 0) {
context.html('<div class="text-center">'+
'<span class="fa-stack fa-5x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-info-circle fa-stack-1x fa-inverse"></i>'+
'</span>'+
'<br>'+
'<br>'+
'<span style="font-size: 18px; color: #999">'+
tr("There are no templates available")+
'</span>'+
'</div>');
} else {
$('#'+tableID+'_table').html(
'<ul id="'+tableID+'_ul" class="large-block-grid-3 medium-block-grid-3 small-block-grid-1 text-center"></ul>');
}
return true;
}
provision_system_templates_datatable = $('#provision_system_templates_table').dataTable({
"iDisplayLength": 6,
"sDom" : '<"H">t<"F"lp>',
@ -6004,55 +5997,10 @@ $(document).ready(function(){
{ "mDataProp": "VMTEMPLATE.TEMPLATE.SAVED_TEMPLATE_ID", "sDefaultContent" : "-" }
],
"fnPreDrawCallback": function (oSettings) {
// create a thumbs container if it doesn't exist. put it in the dataTables_scrollbody div
if (this.$('tr', {"filter": "applied"} ).length == 0) {
this.html('<div class="text-center">'+
'<span class="fa-stack fa-5x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-info-circle fa-stack-1x fa-inverse"></i>'+
'</span>'+
'<br>'+
'<br>'+
'<span style="font-size: 18px; color: #999">'+
tr("There are no templates available")+
'</span>'+
'</div>');
} else {
$("#provision_system_templates_table").html('<ul id="provision_system_templates_ul" class="large-block-grid-3 medium-block-grid-3 small-block-grid-1 text-center"></ul>');
}
return true;
initializeTemplateCards(this, "provision_system_templates")
},
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var data = aData.VMTEMPLATE;
var logo;
if (data.TEMPLATE.LOGO) {
logo = '<span class="provision-logo" href="#">'+
'<img src="'+data.TEMPLATE.LOGO+'">'+
'</span>';
} else {
logo = '<span style="color: #bfbfbf; font-size: 60px;">'+
'<i class="fa fa-fw fa-file-text-o"/>'+
'</span>';
}
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
'<li style="height: 85px" class="provision-bullet-item">'+
logo +
'</li>'+
'<li class="provision-description">'+
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>').appendTo($("#provision_system_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
appendTemplateCard(aData, "provision_system_templates");
return nRow;
}
});
@ -6072,55 +6020,10 @@ $(document).ready(function(){
{ "mDataProp": "VMTEMPLATE.PERMISSIONS.GROUP_U" }
],
"fnPreDrawCallback": function (oSettings) {
// create a thumbs container if it doesn't exist. put it in the dataTables_scrollbody div
if (this.$('tr', {"filter": "applied"} ).length == 0) {
this.html('<div class="text-center">'+
'<span class="fa-stack fa-5x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-info-circle fa-stack-1x fa-inverse"></i>'+
'</span>'+
'<br>'+
'<br>'+
'<span style="font-size: 18px; color: #999">'+
tr("There are no templates available. Please contact your cloud administrator")+
'</span>'+
'</div>');
} else {
$("#provision_vdc_templates_table").html('<ul id="provision_vdc_templates_ul" class="large-block-grid-3 medium-block-grid-3 small-block-grid-1 text-center"></ul>');
}
return true;
initializeTemplateCards(this, "provision_vdc_templates")
},
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var data = aData.VMTEMPLATE;
var logo;
if (data.TEMPLATE.LOGO) {
logo = '<span class="provision-logo" href="#">'+
'<img src="'+data.TEMPLATE.LOGO+'">'+
'</span>';
} else {
logo = '<span style="color: #bfbfbf; font-size: 60px;">'+
'<i class="fa fa-fw fa-file-text-o"/>'+
'</span>';
}
var li = ('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
'<li style="height: 85px" class="provision-bullet-item">'+
logo +
'</li>'+
'<li class="provision-description">'+
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>').appendTo($("#provision_vdc_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
appendTemplateCard(aData, "provision_vdc_templates");
return nRow;
}
});
@ -6140,56 +6043,10 @@ $(document).ready(function(){
{ "mDataProp": "VMTEMPLATE.PERMISSIONS.GROUP_U" }
],
"fnPreDrawCallback": function (oSettings) {
// create a thumbs container if it doesn't exist. put it in the dataTables_scrollbody div
if (this.$('tr', {"filter": "applied"} ).length == 0) {
this.html('<div class="text-center">'+
'<span class="fa-stack fa-5x" style="color: #dfdfdf">'+
'<i class="fa fa-cloud fa-stack-2x"></i>'+
'<i class="fa fa-info-circle fa-stack-1x fa-inverse"></i>'+
'</span>'+
'<br>'+
'<br>'+
'<span style="font-size: 18px; color: #999">'+
tr("There are no templates available. Please contact your cloud administrator")+
'</span>'+
'</div>');
} else {
$("#provision_saved_templates_table").html('<ul id="provision_saved_templates_ul" class="large-block-grid-3 medium-block-grid-3 small-block-grid-1 text-center"></ul>');
}
return true;
initializeTemplateCards(this, "provision_saved_templates")
},
"fnRowCallback": function( nRow, aData, iDisplayIndex, iDisplayIndexFull ) {
var data = aData.VMTEMPLATE;
var logo;
if (data.TEMPLATE.LOGO) {
logo = '<span class="provision-logo" href="#">'+
'<img src="'+data.TEMPLATE.LOGO+'">'+
'</span>';
} else {
logo = '<span style="color: #bfbfbf; font-size: 60px;">'+
'<i class="fa fa-fw fa-file-text-o"/>'+
'</span>';
}
var li = $('<li>'+
'<ul class="provision-pricing-table hoverable only-one" opennebula_id="'+data.ID+'">'+
'<li class="provision-title" title="'+data.NAME+'">'+
data.NAME+
'</li>'+
'<li style="height: 85px" class="provision-bullet-item">'+
logo +
'</li>'+
'<li class="provision-description">'+
(data.TEMPLATE.DESCRIPTION || '...')+
'</li>'+
'</ul>'+
'</li>').appendTo($("#provision_saved_templates_ul"));
$(".provision-pricing-table", li).data("opennebula", aData);
appendTemplateCard(aData, "provision_saved_templates");
return nRow;
}
});
@ -6506,7 +6363,7 @@ $(document).ready(function(){
if (network_attrs.length > 0) {
generate_provision_network_accordion(
$(".provision_network_selector", context));
$(".provision_network_selector", context), true);
$.each(network_attrs, function(index, vnet_attr){
generate_provision_network_table(

View File

@ -118,10 +118,14 @@ var support_actions = {
//addTemplateElement(request, response);
//notifyCustom(tr("Request created"), " ID: " + response.VMTEMPLATE.ID, false)
},
error: function(request, response){
error: function(request, error_json){
popFormDialog("create_support_request_form", $("#support-tab"));
$("a[href=back]", $("#support-tab")).trigger("click");
show_support_connect();
if (error_json.error.http_status=="403") {
notifyError(error_json.error.message);
} else {
$("a[href=back]", $("#support-tab")).trigger("click");
show_support_connect();
}
}
},

View File

@ -1879,7 +1879,7 @@ function wizard_tab_dd(){
}
if (Config.isTemplateCreationTabEnabled('context')){
str += "<dd class='hypervisor only_kvm only_vmware only_xen'><a href='#contextTab'><i class='fa fa-folder'></i><br>"+tr("Context")+"</a></dd>";
str += "<dd class='hypervisor only_kvm only_vmware only_xen only_vcenter'><a href='#contextTab'><i class='fa fa-folder'></i><br>"+tr("Context")+"</a></dd>";
}
if (Config.isTemplateCreationTabEnabled('scheduling')){

View File

@ -657,10 +657,8 @@ function buildUserJSON(dialog){
if (driver == 'custom'){
driver = $('input[name="custom_auth"]', dialog).val();
}
if (!user_name.length || !user_password.length){
return false;
} else if (driver == "ldap") {
user_password = "-"
}
var user_json = { "user" :
@ -685,6 +683,16 @@ function setupCreateUserDialog(){
//$('button',dialog).button();
$('#driver', dialog).change(function(){
if ($(this).val() == "ldap"){
$('#pass',dialog).hide();
$('label[for="pass"]',dialog).hide();
} else {
$('#pass',dialog).show();
$('label[for="pass"]',dialog).show();
};
});
setupCustomAuthDialog(dialog);
$('#create_user_form',dialog).submit(function(){

View File

@ -30,14 +30,6 @@ function loadVNC(){
}
loadVNC();
function calculate_isHybrid(vm_info){
return vm_info.USER_TEMPLATE.HYPERVISOR &&
(vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "vcenter"
|| vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "ec2"
|| vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "azure"
|| vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "softlayer")
}
var VNCstates=[
tr("RUNNING"),
tr("SHUTDOWN"),
@ -237,6 +229,7 @@ var vm_actions = {
if (Sunstone.rightInfoVisible(tab)) {
// individual view
updateVMInfo(request, response);
$(".right-info-tabs > dd.active > a", "#vms-tab").trigger("click");
}
// datatable row
@ -972,63 +965,6 @@ function str_start_time(vm){
return pretty_time(vm.STIME);
};
// Return the IP or several IPs of a VM
function ip_str(vm){
var isHybrid = calculate_isHybrid(vm);
if (isHybrid)
{
switch(vm.USER_TEMPLATE.HYPERVISOR.toLowerCase())
{
case "vcenter":
ip = vm.TEMPLATE.GUEST_IP?vm.TEMPLATE.GUEST_IP:"--";
break;
case "ec2":
ip = vm.TEMPLATE.IP_ADDRESS?vm.TEMPLATE.IP_ADDRESS:"--";
break;
case "azure":
ip = vm.TEMPLATE.IPADDRESS?vm.TEMPLATE.IPADDRESS:"--";
break;
case "softlayer":
ip = vm.TEMPLATE.PRIMARYIPADDRESS?vm.TEMPLATE.PRIMARYIPADDRESS:"--";
break;
default:
ip = "--";
}
}
else
{
var nic = vm.TEMPLATE.NIC;
if (nic == undefined){
return '--';
}
if (!$.isArray(nic)){
nic = [nic];
}
ip = '';
$.each(nic, function(index,value){
if (value.IP){
ip += value.IP+'<br />';
}
if (value.IP6_GLOBAL){
ip += value.IP6_GLOBAL+'<br />';
}
if (value.IP6_ULA){
ip += value.IP6_ULA+'<br />';
}
});
}
return ip;
};
// Returns an array formed by the information contained in the vm_json
// and ready to be introduced in a dataTable
function vMachineElementArray(vm_json){
@ -1994,19 +1930,19 @@ function setupAttachDiskDialog(){
<label style="border-style: inset; background-color: lightgrey" type="text" name="vm_id" id="vm_id" disabled/>\
</div>\
</div>' +
generate_disk_tab_content("attach_disk", "attach_disk") +
generate_disk_tab_content("attach_disk") +
'<div class="reveal-footer">\
<div class="form_buttons">\
<button class="button radius right success" id="attach_disk_button" type="submit" value="VM.attachdisk">'+tr("Attach")+'</button>\
</div>\
</div>\
<a class="close-reveal-modal">&#215;</a>\
</form></div>')
</form></div>');
dialog.addClass("reveal-modal large max-height").attr("data-reveal", "");
setupTips(dialog);
setup_disk_tab_content(dialog, "attach_disk", "attach_disk")
setup_disk_tab_content(dialog, "attach_disk");
$('#attach_disk_form',dialog).submit(function(){
var vm_id = $('#vm_id', this).text();
@ -2039,6 +1975,7 @@ function setupAttachDiskDialog(){
function popUpAttachDiskDialog(vm_id){
$('#vm_id',$attach_disk_dialog).text(vm_id);
refreshImageTableSelect($attach_disk_dialog, "attach_disk");
$attach_disk_dialog.foundation().foundation('reveal', 'open');
}
@ -2326,6 +2263,7 @@ function setupAttachNicDialog(){
function popUpAttachNicDialog(vm_id){
$('#vm_id',$attach_nic_dialog).text(vm_id);
refreshImageTableSelect($attach_nic_dialog, "attach_nic");
$attach_nic_dialog.foundation().foundation('reveal', 'open');
}

View File

@ -1216,12 +1216,12 @@ function setupCreateVNetDialog() {
$('select#vlan,label[for="vlan"]',$create_vn_dialog).show().prop('wizard_field_disabled', false);
$('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show().prop('wizard_field_disabled', false);
$('input#phydev',$create_vn_dialog).attr('required', '');
$('input#phydev',$create_vn_dialog).removeAttr('required');
$('input#bridge',$create_vn_dialog).removeAttr('required');
break;
case "ebtables":
$('input#bridge,label[for="bridge"]',$create_vn_dialog).show().prop('wizard_field_disabled', false);
$('input#phydev,label[for="phydev"]',$create_vn_dialog).show().prop('wizard_field_disabled', false);
$('input#phydev,label[for="phydev"]',$create_vn_dialog).hide().prop('wizard_field_disabled', true);
$('select#vlan,label[for="vlan"]',$create_vn_dialog).show().prop('wizard_field_disabled', false);
$('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).hide().prop('wizard_field_disabled', true);
@ -1666,10 +1666,12 @@ function setupAddARDialog(){
setup_ar_tab_content(dialog, "add_ar")
$('#submit_ar_reset_button').click(function(){
var vnet_id = $('#vnet_id', $add_ar_dialog).text();
$add_ar_dialog.html("");
setupAddARDialog();
popUpAddAR();
popUpAddAR(vnet_id);
});
$('#add_ar_form',dialog).on('invalid', function () {

View File

@ -5070,11 +5070,11 @@ function accountingGraphs(div, opt){
'<div class="row">\
<div id="acct_start_time_container" class="left columns">\
<label for="acct_start_time">'+tr("Start time")+'</label>\
<input id="acct_start_time" type="date" placeholder="2013/12/30"/>\
<input id="acct_start_time" type="date" placeholder="2013-06-30"/>\
</div>\
<div id="acct_end_time_container" class="left columns">\
<label for="acct_end_time">'+tr("End time")+'</label>\
<input id="acct_end_time" type="date" placeholder="'+tr("Today")+'"/>\
<input id="acct_end_time" type="date" placeholder="2013-12-30"/>\
</div>\
<div id="acct_group_by_container" class="left columns">\
<label for="acct_group_by">' + tr("Group by") + '</label>\
@ -5268,6 +5268,10 @@ function accountingGraphs(div, opt){
//--------------------------------------------------------------------------
// Submit request
//--------------------------------------------------------------------------
function dateFromString(str) {
var a = $.map(str.split(/[^0-9]/), function(s) { return parseInt(s, 10) });
return Date.UTC(a[0], a[1]-1 || 0, a[2] || 1, a[3] || 0, a[4] || 0, a[5] || 0, a[6] || 0);
}
$("#acct_submit", div).on("click", function(){
var start_time = -1;
@ -5278,7 +5282,8 @@ function accountingGraphs(div, opt){
notifyError(tr("Time range start is mandatory"));
return false;
}else{
start_time = Date.parse(v+' UTC');
start_time = dateFromString(v)
//start_time = Date.parse(v+' UTC');
if (isNaN(start_time)){
notifyError(tr("Time range start is not a valid date. It must be YYYY/MM/DD"));
@ -5291,8 +5296,7 @@ function accountingGraphs(div, opt){
var v = $("#acct_end_time", div).val();
if (v != ""){
end_time = Date.parse(v+' UTC');
end_time = dateFromString(v)
if (isNaN(end_time)){
notifyError(tr("Time range end is not a valid date. It must be YYYY/MM/DD"));
@ -5360,7 +5364,7 @@ function fillAccounting(div, req, response, no_table) {
// start_time is mandatory
var start = new Date(options.start_time * 1000);
start.setHours(0,0,0,0);
start.setUTCHours(0,0,0,0);
var end = new Date();
@ -6658,9 +6662,9 @@ function setupResourceTableSelect(section, context_id, options) {
var dataTable_select = $('#datatable_'+context_id, section).dataTable(options.dataTable_options);
$('#refresh_button_'+context_id, section).die();
$('#refresh_button_'+context_id, section).off("click");
$('#refresh_button_'+context_id, section).live('click', function(){
section.on('click', '#refresh_button_'+context_id, function(){
options.update_fn($('table[id=datatable_'+context_id+']', section).dataTable());
});
@ -7111,3 +7115,63 @@ function getInternetExplorerVersion(){
}
return rv;
}
// Return true if the VM has a hybrid section
function calculate_isHybrid(vm_info){
return vm_info.USER_TEMPLATE.HYPERVISOR &&
(vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "vcenter"
|| vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "ec2"
|| vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "azure"
|| vm_info.USER_TEMPLATE.HYPERVISOR.toLowerCase() == "softlayer")
}
// Return the IP or several IPs of a VM
function ip_str(vm, divider){
var divider = divider || "<br>"
var isHybrid = calculate_isHybrid(vm);
var nic = vm.TEMPLATE.NIC;
if (nic == undefined) {
if (isHybrid) {
switch(vm.USER_TEMPLATE.HYPERVISOR.toLowerCase()) {
case "vcenter":
ip = vm.TEMPLATE.GUEST_IP?vm.TEMPLATE.GUEST_IP:"--";
break;
case "ec2":
ip = vm.TEMPLATE.IP_ADDRESS?vm.TEMPLATE.IP_ADDRESS:"--";
break;
case "azure":
ip = vm.TEMPLATE.IPADDRESS?vm.TEMPLATE.IPADDRESS:"--";
break;
case "softlayer":
ip = vm.TEMPLATE.PRIMARYIPADDRESS?vm.TEMPLATE.PRIMARYIPADDRESS:"--";
break;
default:
ip = "--";
}
} else {
return '--';
}
} else {
if (!$.isArray(nic)){
nic = [nic];
}
ip = '';
$.each(nic, function(index,value){
if (value.IP){
ip += value.IP+divider;
}
if (value.IP6_GLOBAL){
ip += value.IP6_GLOBAL+divider;
}
if (value.IP6_ULA){
ip += value.IP6_ULA+divider;
}
});
}
return ip;
};

View File

@ -122,10 +122,13 @@ get '/support/request' do
pending_requests = 0
one_zrequests = {
"REQUEST_POOL" => {
"REQUEST" => []
}
}
if zrequests.size > 0
one_zrequests["REQUEST_POOL"]["REQUEST"] = []
end
zrequests.each { |zrequest|
if zrequest.status == "pending"
pending_requests += 1
@ -158,16 +161,21 @@ post '/support/request' do
check_zendesk_api_gem
body_hash = JSON.parse(@request_body)
zrequest = zendesk_client.requests.create({
:subject => body_hash['subject'],
:comment => { :value => body_hash['description'] },
:custom_fields => [
{:id => 391197, :value => body_hash['severity']},
{:id => 391130, :value => body_hash['opennebula_version']}
]
})
[201, JSON.pretty_generate(zrequest_to_one(zrequest))]
zrequest = ticket = ZendeskAPI::Request.new(zendesk_client, {
:subject => body_hash['subject'],
:comment => { :value => body_hash['description'] },
:custom_fields => [
{:id => 391197, :value => body_hash['severity']},
{:id => 391130, :value => body_hash['opennebula_version']}
]
})
if zrequest.save
[201, JSON.pretty_generate(zrequest_to_one(zrequest))]
else
[403, Error.new(zrequest.errors["base"][0]["description"]).to_json]
end
end
post '/support/request/:id/action' do

View File

@ -29,6 +29,8 @@ TARGET="$3"
TARGET_INDEX="$4"
DRV_ACTION="$5"
ATTACH_FILE="$SOURCE.attach"
XPATH="${DRIVER_PATH}/../../datastore/xpath.rb -b $DRV_ACTION"
unset i j XPATH_ELEMENTS
@ -37,20 +39,26 @@ DISK_XPATH="/VMM_DRIVER_ACTION_DATA/VM/TEMPLATE/DISK[ATTACH='YES']"
while IFS= read -r -d '' element; do
XPATH_ELEMENTS[i++]="$element"
done < <($XPATH $DISK_XPATH/DRIVER \
done < <($XPATH /VMM_DRIVER_ACTION_DATA/VM/ID \
$DISK_XPATH/DRIVER \
$DISK_XPATH/TYPE \
$DISK_XPATH/READONLY \
$DISK_XPATH/CACHE \
$DISK_XPATH/SOURCE \
$DISK_XPATH/DISK_ID \
$DISK_XPATH/CLONE \
$DISK_XPATH/CEPH_HOST \
$DISK_XPATH/CEPH_SECRET \
$DISK_XPATH/CEPH_USER)
VMID="${XPATH_ELEMENTS[j++]}"
DRIVER="${XPATH_ELEMENTS[j++]:-$DEFAULT_TYPE}"
TYPE="${XPATH_ELEMENTS[j++]}"
READONLY="${XPATH_ELEMENTS[j++]}"
CACHE="${XPATH_ELEMENTS[j++]}"
IMG_SRC="${XPATH_ELEMENTS[j++]}"
DISK_ID="${XPATH_ELEMENTS[j++]}"
CLONE="${XPATH_ELEMENTS[j++]}"
CEPH_HOST="${XPATH_ELEMENTS[j++]}"
CEPH_SECRET="${XPATH_ELEMENTS[j++]}"
CEPH_USER="${XPATH_ELEMENTS[j++]}"
@ -72,9 +80,14 @@ rbd)
TYPE_SOURCE="protocol"
TYPE_XML="network"
SOURCE="rbd"
SOURCE_ARGS="name='$IMG_SRC'"
DEVICE="disk"
if [ "$CLONE" = "YES" ]; then
SOURCE_ARGS="name='${IMG_SRC}-${VMID}-${DISK_ID}'"
else
SOURCE_ARGS="name='${IMG_SRC}'"
fi
for host in $CEPH_HOST ; do
BCK_IFS=$IFS
IFS=':'
@ -120,8 +133,6 @@ else
READONLY=""
fi
ATTACH_FILE="$SOURCE.attach"
cat <<EOF > $ATTACH_FILE
<disk type='$TYPE_XML' device='$DEVICE'>
<driver name='qemu' type='$DRIVER' $CACHE/>

View File

@ -39,6 +39,7 @@ $: << LIB_LOCATION+'/ruby'
require 'rbvmomi'
require 'yaml'
require 'opennebula'
require 'base64'
module VCenterDriver
@ -50,6 +51,24 @@ module VCenterDriver
class VIClient
attr_reader :vim, :one, :root, :cluster, :user, :pass, :host
def get_entities(folder, type, entities=[])
return nil if folder == []
folder.childEntity.each do |child|
name, junk = child.to_s.split('(')
case name
when "Folder"
get_entities(child, type, entities)
when type
entities.push(child)
end
end
return entities
end
############################################################################
# Initializr the VIClient, and creates an OpenNebula client. The parameters
# are obtained from the associated OpenNebula host
@ -74,9 +93,10 @@ class VIClient
initialize_vim(connection)
@root.childEntity.each {|dc|
ccrs = dc.hostFolder.childEntity.grep(
RbVmomi::VIM::ClusterComputeResource)
datacenters = get_entities(@root, 'Datacenter')
datacenters.each {|dc|
ccrs = get_entities(dc.hostFolder, 'ClusterComputeResource')
next if ccrs.nil?
@ -118,9 +138,15 @@ class VIClient
# @param uuid [String] the UUID of the VM or VM Template
########################################################################
def find_vm_template(uuid)
vms = @dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine)
vms = get_entities(@dc.vmFolder, 'VirtualMachine')
return vms.find{ |v| v.config.uuid == uuid }
return vms.find do |v|
begin
v.config && v.config.uuid == uuid
rescue ManagedObjectNotFound
false
end
end
end
########################################################################
@ -132,11 +158,10 @@ class VIClient
def hierarchy
vc_hosts = {}
@root.childEntity.each { |dc|
ccrs = dc.hostFolder.childEntity.grep(
RbVmomi::VIM::ClusterComputeResource)
datacenters = get_entities(@root, 'Datacenter')
datacenters.each { |dc|
ccrs = get_entities(dc.hostFolder, 'ClusterComputeResource')
vc_hosts[dc.name] = ccrs.collect { |c| c.name }
}
@ -151,9 +176,10 @@ class VIClient
def vm_templates
vm_templates = {}
@root.childEntity.each { |dc|
datacenters = get_entities(@root, 'Datacenter')
vms = dc.vmFolder.childEntity.grep(RbVmomi::VIM::VirtualMachine)
datacenters.each { |dc|
vms = get_entities(dc.vmFolder, 'VirtualMachine')
tmp = vms.select { |v| v.config.template == true }
@ -746,6 +772,8 @@ private
raise "Cannot find host id in deployment file history." if hid.nil?
context = xml.root.elements["//TEMPLATE/CONTEXT"]
connection = VIClient.new(hid)
vc_template = connection.find_vm_template(uuid)
@ -775,11 +803,26 @@ private
vnc_listen = vnc_listen.text
end
config_array = []
if vnc_port
spec = RbVmomi::VIM.VirtualMachineConfigSpec(:extraConfig =>
config_array +=
[{:key=>"remotedisplay.vnc.enabled", :value=>"TRUE"},
{:key=>"remotedisplay.vnc.port", :value=>vnc_port.text},
{:key=>"remotedisplay.vnc.ip", :value=>vnc_listen}])
{:key=>"remotedisplay.vnc.ip", :value=>vnc_listen}]
end
if context
# Remove <CONTEXT> (9) and </CONTEXT>\n (11)
context_text = Base64.encode64(context.to_s[9..-11])
config_array +=
[{:key=>"guestinfo.opennebula.context",
:value=>context_text}]
end
if config_array != []
spec_hash = {:extraConfig =>config_array}
spec = RbVmomi::VIM.VirtualMachineConfigSpec(spec_hash)
rc.ReconfigVM_Task(:spec => spec).wait_for_completion
end