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

Feature #407: Added Sunstone support to template update in Templates and Images.

Fixed other issues, indents, tabs...
This commit is contained in:
Hector Sanjuan 2011-06-09 17:29:34 +02:00 committed by Ruben S. Montero
parent f8e64561aa
commit 72fafbdb3f
15 changed files with 2171 additions and 2241 deletions

View File

@ -45,7 +45,7 @@ module OpenNebulaJSON
end
def chown(params=Hash.new)
super(params['owner_id'].to_i,-1)
super(params['owner_id'].to_i)
end
end
end

View File

@ -59,7 +59,7 @@ module OpenNebulaJSON
end
def update(params=Hash.new)
super(params['name'], params['value'])
super(params['template_raw'])
end
def remove_attr(params=Hash.new)

View File

@ -43,23 +43,18 @@ module OpenNebulaJSON
rc = case action_hash['perform']
when "publish" then self.publish
when "rm_attr" then self.remove_attr(action_hash['params'])
when "unpublish" then self.unpublish
when "update" then self.update(action_hash['params'])
when "chown" then self.chown(action_hash['params'])
when "chown" then self.chown(action_hash['params'])
else
error_msg = "#{action_hash['perform']} action not " <<
" available for this resource"
OpenNebula::Error.new(error_msg)
end
end
def update(params=Hash.new)
super(params['name'], params['value'])
end
def remove_attr(params=Hash.new)
super(params['name'])
def update(params=Hash.new)
super(params['template_raw'])
end
def chown(params=Hash.new)

View File

@ -87,6 +87,19 @@ class SunstoneServer
end
end
############################################################################
#
############################################################################
def get_template(kind,id)
resource = retrieve_resource(kind,id)
if OpenNebula.is_error?(resource)
return [404, resource.to_json]
else
template_str = resource.template_str(true)
return [200, {:template => template_str}.to_json]
end
end
############################################################################
#
############################################################################

View File

@ -235,19 +235,19 @@ div.tip span.man_icon {
display:inline-block!important;
}
span.tipspan {
position: fixed;
display:block;
padding:4px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #353735;
margin-left:2px;
margin-right:5px;
background-color: white;
span.tipspan,div.full_info {
position: fixed;
display:block;
padding:4px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
border: 1px solid #353735;
margin-left:2px;
margin-right:5px;
background-color: white;
color: #353735;
font-size:10px;
font-size:10px;
}
.vm_section input {
float:none;

View File

@ -1783,7 +1783,71 @@ var OpenNebula = {
}
});
},
"fetch_template" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var method = "fetch_template";
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, id);
$.ajax({
url: "/image/" + id + "/template",
type: "GET",
dataType:"json",
success: function(response)
{
if (callback)
{
callback(request,response);
}
},
error: function(response)
{
if(callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"update": function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var template_raw = params.data.extra_param;
var template_obj = {"template_raw": template_raw}
var method = "update";
var action = OpenNebula.Helper.action(method, template_obj);
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, [id, template_obj]);
$.ajax({
url: "/image/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function(response)
{
if (callback)
{
callback(request, response);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"delete": function(params)
{
var callback = params.success;
@ -1874,82 +1938,6 @@ var OpenNebula = {
}
});
},
"addattr": function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "update";
var action = OpenNebula.Helper.action(method, {
"name" : name,
"value" : value
});
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
$.ajax({
url: "/image/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function(response)
{
if (callback)
{
callback(request, response);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"rmattr": function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "rm_attr";
var action = OpenNebula.Helper.action(method, {
"name" : name
});
var resource = OpenNebula.Image.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name]);
$.ajax({
url: "/image/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function(response)
{
if (callback)
{
callback(request, response);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"enable": function(params)
{
var callback = params.success;
@ -2188,95 +2176,49 @@ var OpenNebula = {
});
},
"addattr" : function(params)
"fetch_template" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "update";
var action = OpenNebula.Helper.action(method, {
"name" : name,
"value" : value
});
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
var method = "fetch_template";
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, id);
$.ajax({
url: "/template/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
url: "/template/" + id + "/template",
type: "GET",
dataType:"json",
success: function(response)
{
if (callback)
{
callback(request, response);
callback(request,response);
}
},
error: function(response)
{
if (callback_error)
if(callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
});
},
"update" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var template_raw = params.data.extra_param;
var template_obj = {"template_raw": template_raw}
var method = "update";
var action = OpenNebula.Helper.action(method, {
"name" : name,
"value" : value
});
var action = OpenNebula.Helper.action(method, template_obj);
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name, value]);
$.ajax({
url: "/template/" + id + "/action",
type: "POST",
data: JSON.stringify(action),
success: function(response)
{
if (callback)
{
callback(request, response);
}
},
error: function(response)
{
if (callback_error)
{
callback_error(request, OpenNebula.Error(response));
}
}
});
},
"rmattr" : function(params)
{
var callback = params.success;
var callback_error = params.error;
var id = params.data.id;
var name = params.data.name;
var value = params.data.value;
var method = "rm_attr";
var action = OpenNebula.Helper.action(method, {
"name" : name
});
var resource = OpenNebula.Template.resource;
var request = OpenNebula.Helper.request(resource,method, [id, name]);
var request = OpenNebula.Helper.request(resource,method, [id, template_obj]);
$.ajax({
url: "/template/" + id + "/action",
@ -2298,6 +2240,7 @@ var OpenNebula = {
}
});
},
"publish" : function(params)
{
var callback = params.success;

View File

@ -44,7 +44,6 @@ var hosts_tab_content =
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>Name</th>\
<th>Group</th>\
<th>Running VMs</th>\
<th>CPU Use</th>\
<th>Memory use</th>\
@ -318,7 +317,6 @@ function hostElementArray(host_json){
return [ '<input type="checkbox" id="host_'+host.ID+'" name="selected_items" value="'+host.ID+'"/>',
host.ID,
host.NAME,
getGroupName(host.GID),
host.HOST_SHARE.RUNNING_VMS, //rvm
pb_cpu,
pb_mem,
@ -385,79 +383,79 @@ function updateHostsView (request,host_list){
//Updates the host info panel tab's content and pops it up
function updateHostInfo(request,host){
var host_info = host.HOST;
//Information tab
var info_tab = {
title : "Host information",
content :
'<table id="info_host_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host information - '+host_info.NAME+'</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+host_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("host",host_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Group</td>\
<td class="value_td">'+host_info.GID+'</td>\
</tr>\
<tr>\
<td class="key_td">IM MAD</td>\
<td class="value_td">'+host_info.IM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">VM MAD</td>\
<td class="value_td">'+host_info.VM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">TM MAD</td>\
<td class="value_td">'+host_info.TM_MAD+'</td>\
</tr>\
</table>\
<table id="host_shares_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host shares</th></tr>\
</thead>\
<tr>\
<td class="key_td">Max Mem</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (real)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.USED_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (allocated)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (real)</td>\
<td class="value_td">'+host_info.HOST_SHARE.USED_CPU+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (allocated)</td>\
<td class="value_td">'+host_info.HOST_SHARE.CPU_USAGE+'</td>\
</tr>\
<tr>\
<td class="key_td">Running VMs</td>\
<td class="value_td">'+host_info.HOST_SHARE.RUNNING_VMS+'</td>\
</tr>\
</table>'
<thead>\
<tr><th colspan="2">Host information - '+host_info.NAME+'</th></tr>\
</thead>\
<tbody>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+host_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("host",host_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">IM MAD</td>\
<td class="value_td">'+host_info.IM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">VM MAD</td>\
<td class="value_td">'+host_info.VM_MAD+'</td>\
</tr>\
<tr>\
<td class="key_td">TM MAD</td>\
<td class="value_td">'+host_info.TM_MAD+'</td>\
</tr>\
</tbody>\
</table>\
<table id="host_shares_table" class="info_table">\
<thead>\
<tr><th colspan="2">Host shares</th></tr>\
</thead>\
<tbody>\
<tr>\
<td class="key_td">Max Mem</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (real)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.USED_MEM)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Mem (allocated)</td>\
<td class="value_td">'+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (real)</td>\
<td class="value_td">'+host_info.HOST_SHARE.USED_CPU+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU (allocated)</td>\
<td class="value_td">'+host_info.HOST_SHARE.CPU_USAGE+'</td>\
</tr>\
<tr>\
<td class="key_td">Running VMs</td>\
<td class="value_td">'+host_info.HOST_SHARE.RUNNING_VMS+'</td>\
</tr>\
</tbody>\
</table>'
}
//Template tab
var template_tab = {
title : "Host template",
content :
'<table id="host_template_table" class="info_table">\
<thead><tr><th colspan="2">Host template</th></tr></thead>'+
prettyPrintJSON(host_info.TEMPLATE)+
'</table>'
content :
'<table id="host_template_table" class="info_table">\
<thead><tr><th colspan="2">Host template</th></tr></thead>'+
prettyPrintJSON(host_info.TEMPLATE)+
'</table>'
}
var monitor_tab = {
@ -551,7 +549,7 @@ $(document).ready(function(){
dataTable_hosts.fnClearTable();
addElement([
spinner,
'','','','','','',''],dataTable_hosts);
'','','','','',''],dataTable_hosts);
Sunstone.runAction("Host.list");
setupCreateHostDialog();

View File

@ -16,7 +16,7 @@
/*Images tab plugin*/
var images_tab_content =
var images_tab_content =
'<form id="image_form" action="" action="javascript:alert(\'js error!\');">\
<div class="action_blocks">\
</div>\
@ -25,7 +25,8 @@ var images_tab_content =
<tr>\
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>User</th>\
<th>Owner</th>\
<th>Group</th>\
<th>Name</th>\
<th>Type</th>\
<th>Registration time</th>\
@ -42,116 +43,116 @@ var images_tab_content =
var create_image_tmpl =
'<div id="img_tabs">\
<ul><li><a href="#img_easy">Wizard</a></li>\
<li><a href="#img_manual">Advanced mode</a></li>\
</ul>\
<div id="img_easy">\
<form id="create_image_form_easy" action="">\
<p style="font-size:0.8em;text-align:right;"><i>Fields marked with <span style="display:inline-block;" class="ui-icon ui-icon-alert" /> are mandatory</i><br />\
<fieldset>\
<div class="img_param img_man">\
<label for="img_name">Name:</label>\
<input type="text" name="img_name" id="img_name" />\
<div class="tip">Name that the Image will get. Every image must have a unique name.</div>\
</div>\
<div class="img_param">\
<label for="img_desc">Description:</label>\
<textarea name="img_desc" id="img_desc" style="height:4em"></textarea>\
<div class="tip">Human readable description of the image for other users.</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="img_param">\
<label for="img_type">Type:</label>\
<select name="img_type" id="img_type">\
<option value="OS">OS</option>\
<option value="CDROM">CD-ROM</option>\
<option value="DATABLOCK">Datablock</option>\
</select>\
<div class="tip">Type of the image, explained in detail in the following section. If omitted, the default value is the one defined in oned.conf (install default is OS).</div>\
</div>\
<div class="img_param">\
<label for="img_public">Public:</label>\
<input type="checkbox" id="img_public" name="img_public" value="YES" />\
<div class="tip">Public scope of the image</div>\
</div>\
<div class="img_param">\
<label for="img_persistent">Persistent:</label>\
<input type="checkbox" id="img_persistent" name="img_persistent" value="YES" />\
<div class="tip">Persistence of the image</div>\
</div>\
<div class="img_param">\
<label for="img_dev_prefix">Device prefix:</label>\
<input type="text" name="img_dev_prefix" id="img_dev_prefix" />\
<div class="tip">Prefix for the emulated device this image will be mounted at. For instance, hd, sd. If omitted, the default value is the one defined in oned.conf (installation default is hd).</div>\
</div>\
<div class="img_param">\
<label for="img_bus">Bus:</label>\
<select name="img_bus" id="img_bus">\
<option value="IDE">IDE</option>\
<option value="SCSI">SCSI</option>\
<option value="virtio">Virtio (KVM)</option>\
</select>\
<div class="tip">Type of disk device to emulate.</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="" id="src_path_select">\
<label style="height:3em;">Path vs. source:</label>\
<input type="radio" name="src_path" id="path_img" value="path" />\
<ul><li><a href="#img_easy">Wizard</a></li>\
<li><a href="#img_manual">Advanced mode</a></li>\
</ul>\
<div id="img_easy">\
<form id="create_image_form_easy" action="">\
<p style="font-size:0.8em;text-align:right;"><i>Fields marked with <span style="display:inline-block;" class="ui-icon ui-icon-alert" /> are mandatory</i><br />\
<fieldset>\
<div class="img_param img_man">\
<label for="img_name">Name:</label>\
<input type="text" name="img_name" id="img_name" />\
<div class="tip">Name that the Image will get. Every image must have a unique name.</div>\
</div>\
<div class="img_param">\
<label for="img_desc">Description:</label>\
<textarea name="img_desc" id="img_desc" style="height:4em"></textarea>\
<div class="tip">Human readable description of the image for other users.</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="img_param">\
<label for="img_type">Type:</label>\
<select name="img_type" id="img_type">\
<option value="OS">OS</option>\
<option value="CDROM">CD-ROM</option>\
<option value="DATABLOCK">Datablock</option>\
</select>\
<div class="tip">Type of the image, explained in detail in the following section. If omitted, the default value is the one defined in oned.conf (install default is OS).</div>\
</div>\
<div class="img_param">\
<label for="img_public">Public:</label>\
<input type="checkbox" id="img_public" name="img_public" value="YES" />\
<div class="tip">Public scope of the image</div>\
</div>\
<div class="img_param">\
<label for="img_persistent">Persistent:</label>\
<input type="checkbox" id="img_persistent" name="img_persistent" value="YES" />\
<div class="tip">Persistence of the image</div>\
</div>\
<div class="img_param">\
<label for="img_dev_prefix">Device prefix:</label>\
<input type="text" name="img_dev_prefix" id="img_dev_prefix" />\
<div class="tip">Prefix for the emulated device this image will be mounted at. For instance, hd, sd. If omitted, the default value is the one defined in oned.conf (installation default is hd).</div>\
</div>\
<div class="img_param">\
<label for="img_bus">Bus:</label>\
<select name="img_bus" id="img_bus">\
<option value="IDE">IDE</option>\
<option value="SCSI">SCSI</option>\
<option value="virtio">Virtio (KVM)</option>\
</select>\
<div class="tip">Type of disk device to emulate.</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="" id="src_path_select">\
<label style="height:3em;">Path vs. source:</label>\
<input type="radio" name="src_path" id="path_img" value="path" />\
<label style="float:none">Provide a path</label><br />\
<input type="radio" name="src_path" id="source_img" value="source" />\
<input type="radio" name="src_path" id="source_img" value="source" />\
<label style="float:none">Provide a source</label><br />\
<input type="radio" name="src_path" id="datablock_img" value="datablock" />\
<input type="radio" name="src_path" id="datablock_img" value="datablock" />\
<label style="float:none;vertical-align:top">Create an empty datablock</label>\
<div class="tip">Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.</div><br />\
</div>\
<div class="img_param">\
<label for="img_path">Path:</label>\
<input type="text" name="img_path" id="img_path" />\
<div class="tip">Path to the original file that will be copied to the image repository. If not specified for a DATABLOCK type image, an empty image will be created.</div>\
</div>\
<div class="img_param">\
<label for="img_source">Source:</label>\
<input type="text" name="img_source" id="img_source" />\
<div class="tip">Source to be used in the DISK attribute. Useful for not file-based images.</div>\
</div>\
<div class="img_size">\
<label for="img_size">Size:</label>\
<input type="text" name="img_size" id="img_size" />\
<div class="tip">Size of the datablock in MB.</div>\
</div>\
<div class="img_param">\
<label for="img_fstype">FS type:</label>\
<input type="text" name="img_fstype" id="img_fstype" />\
<div class="tip">Type of file system to be built. This can be any value understood by mkfs unix command.</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_image_submit" value="user/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
<div id="img_manual">\
<form id="create_image_form_manual" action="">\
<fieldset style="border-top:none;">\
<h3 style="margin-bottom:10px;">Write the image template here</h3>\
<textarea id="template" rows="15" style="width:100%;">\
</textarea>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vn_submit_manual" value="vn/create">\
Create\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
<div class="tip">Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.</div><br />\
</div>\
<div class="img_param">\
<label for="img_path">Path:</label>\
<input type="text" name="img_path" id="img_path" />\
<div class="tip">Path to the original file that will be copied to the image repository. If not specified for a DATABLOCK type image, an empty image will be created.</div>\
</div>\
<div class="img_param">\
<label for="img_source">Source:</label>\
<input type="text" name="img_source" id="img_source" />\
<div class="tip">Source to be used in the DISK attribute. Useful for not file-based images.</div>\
</div>\
<div class="img_size">\
<label for="img_size">Size:</label>\
<input type="text" name="img_size" id="img_size" />\
<div class="tip">Size of the datablock in MB.</div>\
</div>\
<div class="img_param">\
<label for="img_fstype">FS type:</label>\
<input type="text" name="img_fstype" id="img_fstype" />\
<div class="tip">Type of file system to be built. This can be any value understood by mkfs unix command.</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_image_submit" value="user/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
<div id="img_manual">\
<form id="create_image_form_manual" action="">\
<fieldset style="border-top:none;">\
<h3 style="margin-bottom:10px;">Write the image template here</h3>\
<textarea id="template" rows="15" style="width:100%;">\
</textarea>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vn_submit_manual" value="vn/create">\
Create\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>\
</div>\
</div>';
var images_select = "";
@ -159,7 +160,7 @@ var image_list_json = {};
var dataTable_images;
var image_actions = {
"Image.register" : {
type: "create",
call: OpenNebula.Image.register,
@ -167,33 +168,33 @@ var image_actions = {
error: onError,
notify:true
},
"Image.create_dialog" : {
type: "custom",
call: popUpCreateImageDialog
},
"Image.list" : {
type: "list",
call: OpenNebula.Image.list,
callback: updateImagesView,
error: onError
},
"Image.show" : {
type : "single",
call: OpenNebula.Image.show,
callback: updateImageElement,
error: onError
},
"Image.showinfo" : {
type: "single",
call: OpenNebula.Image.show,
callback: updateImageInfo,
error: onError
},
"Image.refresh" : {
type: "custom",
call: function () {
@ -201,75 +202,39 @@ var image_actions = {
Sunstone.runAction("Image.list");
},
},
"Image.autorefresh" : {
type: "custom",
call: function() {
OpenNebula.Image.list({timeout: true, success: updateImagesView, error: onError});
}
},
"Image.addattr" : {
type: "multiple",
call: function(obj){
var id_attr = obj.data.id;
var name = $('#img_attr_name').val();
var value = $('#img_attr_value').val();
OpenNebula.Image.addattr(
{data: {
id: id_attr,
name: name,
value: value
},
success: obj.success,
error: obj.error
});
"Image.fetch_template" : {
type: "single",
call: OpenNebula.Image.fetch_template,
callback: function (request,response) {
$('#template_update_dialog #template_update_textarea').val(response.template);
},
callback : function (req) {
Sunstone.runAction("Image.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_images); },
error: onError,
notify: true
notify: false
},
"Image.addattr_dialog" : {
"Image.update_dialog" : {
type: "custom",
call: popUpImageAddattrDialog
call: popUpImageTemplateUpdateDialog
},
"Image.updateattr_dialog" : {
type: "custom",
call: popUpImageAddattrDialog
},
"Image.rmattr" : {
type: "multiple",
call: function(obj){
var id_attr = obj.data.id;
var name = $('#img_attr_name').val();
OpenNebula.Image.rmattr(
{data: {
id: id_attr,
name: name
},
success: obj.success,
error: obj.error
});
"Image.update" : {
type: "single",
call: OpenNebula.Image.update,
callback: function() {
notifyMessage("Template updated correctly");
},
callback: function (req) {
Sunstone.runAction("Image.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_images); },
error: onError,
notify: true
notify: false
},
"Image.rmattr_dialog" : {
type: "custom",
call: popUpImageRmattrDialog,
},
"Image.enable" : {
type: "multiple",
call: OpenNebula.Image.enable,
@ -280,7 +245,7 @@ var image_actions = {
error: onError,
notify: true
},
"Image.disable" : {
type: "multiple",
call: OpenNebula.Image.disable,
@ -291,7 +256,7 @@ var image_actions = {
error: onError,
notify: true
},
"Image.persistent" : {
type: "multiple",
call: OpenNebula.Image.persistent,
@ -302,7 +267,7 @@ var image_actions = {
error: onError,
notify: true
},
"Image.nonpersistent" : {
type: "multiple",
call: OpenNebula.Image.nonpersistent,
@ -313,7 +278,7 @@ var image_actions = {
error: onError,
notify: true
},
"Image.publish" : {
type: "multiple",
call: OpenNebula.Image.publish,
@ -324,7 +289,7 @@ var image_actions = {
error: onError,
notify: true
},
"Image.unpublish" : {
type: "multiple",
call: OpenNebula.Image.unpublish,
@ -335,7 +300,7 @@ var image_actions = {
error: onError,
notify: true
},
"Image.delete" : {
type: "multiple",
call: OpenNebula.Image.delete,
@ -343,7 +308,29 @@ var image_actions = {
elements: function() { return getSelectedNodes(dataTable_images); },
error: onError,
notify: true
}
},
"Image.chown" : {
type: "multiple",
call: OpenNebula.Image.chown,
callback: function (req) {
Sunstone.runAction("Image.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_images); },
error: onError,
notify: true
},
"Image.chgrp" : {
type: "multiple",
call: OpenNebula.Image.chgrp,
callback: function (req) {
Sunstone.runAction("Image.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_images); },
error: onError,
notify: true
}
}
@ -359,19 +346,24 @@ var image_buttons = {
text: "+ New",
condition: True
},
"Image.addattr_dialog" : {
"Image.update_dialog" : {
type: "action",
text: "Add attribute",
text: "Update a template",
condition: True,
alwaysActive: true
},
"Image.chown" : {
type: "confirm_with_select",
text: "Change owner",
select: function() {return users_select;},
tip: "Select the new owner:",
condition: True
},
"Image.updateattr_dialog" : {
type: "action",
text: "Update attribute",
condition: True
},
"Image.rmattr_dialog" : {
type: "action",
text: "Remove attribute",
"Image.chgrp" : {
type: "confirm_with_select",
text: "Change group",
select: function() {return groups_select;},
tip: "Select the new group:",
condition: True
},
"action_list" : {
@ -386,27 +378,27 @@ var image_buttons = {
"Image.disable" : {
type: "action",
text: "Disable",
condition: True
condition: True
},
"Image.publish" : {
type: "action",
text: "Publish",
condition: True
condition: True
},
"Image.unpublish" : {
type: "action",
text: "Unpublish",
condition: True
condition: True
},
"Image.persistent" : {
type: "action",
text: "Make persistent",
condition: True
condition: True
},
"Image.nonpersistent" : {
type: "action",
text: "Make non persistent",
condition: True
condition: True
}
}
},
@ -422,12 +414,12 @@ var image_info_panel = {
title: "Image information",
content: ""
},
"image_template_tab" : {
title: "Image template",
content: ""
}
}
var images_tab = {
@ -448,7 +440,8 @@ function imageElementArray(image_json){
return [
'<input type="checkbox" id="image_'+image.ID+'" name="selected_items" value="'+image.ID+'"/>',
image.ID,
image.USERNAME ? image.USERNAME : getUserName(image.UID),
getUserName(image.UID),
getGroupName(image.GID),
image.NAME,
OpenNebula.Helper.image_type(image.TYPE),
pretty_time(image.REGTIME),
@ -474,9 +467,9 @@ function imageInfoListener(){
//Updates the select input field with an option for each image
function updateImageSelect(){
images_select =
makeSelectOptions(dataTable_images,1,3,8,"DISABLED",2);
images_select =
makeSelectOptions(dataTable_images,1,4,9,"DISABLED",2);
//update static selectors:
//in the VM section
$('div.vm_section#disks select#IMAGE_ID').html(images_select);
@ -517,141 +510,70 @@ function updateImagesView(request, images_list){
}
// Prepare the dialog to add/remove/update image attributes
function setupImageAttributesDialogs(){
//Append to DOM
$('div#dialogs').append('<div id="image_attributes_dialog" title="Image attributes"></div>');
//Put HTML in place
$('#image_attributes_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<fieldset>\
<div id="img_attr_action_desc">\
</div>\
<div>\
<label for="img_attr_name">Name:</label>\
<input type="text" id="img_attr_name" name="img_attr_name" value="" />\
</div>\
<div>\
<label for="img_attr_value">Value:</label>\
<input type="text" id="img_attr_value" name="img_attr_value" value="" />\
</div>\
<div class="form_buttons">\
<button class="action_button" id="img_attr_proceed" value="">OK</button>\
<button id="img_attr_cancel" value="">Cancel</button>\
</div>\
</fieldset>\
</form>');
$('#image_attributes_dialog').dialog({
autoOpen:false,
width:400,
modal:true,
height:220,
resizable:false,
});
$('#image_attributes_dialog button').button();
//Upcase variable names
$('#img_attr_name').keyup(function(){
$(this).val($(this).val().toUpperCase());
});
$('#image_attributes_dialog #img_attr_proceed').click(function(){
$('#image_attributes_dialog').dialog('close');
});
$('#image_attributes_dialog #img_attr_cancel').click(function(){
$('#image_attributes_dialog').dialog('close');
return false;
});
function popUpImageTemplateUpdateDialog(){
$('#template_update_dialog #template_update_button').val("Image");
$('#template_update_dialog #template_update_select').html(images_select);
$('#template_update_dialog').dialog('open');
return false;
}
// Popup a dialog to add/update an attribute
function popUpImageAddattrDialog(){
//Show value field and label
$('#img_attr_value').show();
$('#img_attr_value').prev().show();
var desc = "Please write the name and value of the attribute. It will be added or updated in all selected images:";
$('#img_attr_proceed').val("Image.addattr");
$('#img_attr_action_desc').html(desc);
$('#image_attributes_dialog').dialog('open');
return false;
}
// Popup a dialog to remove an attribute
function popUpImageRmattrDialog(){
//Hide value field and label
$('#img_attr_value').hide();
$('#img_attr_value').prev().hide();
var desc = "Please type the attribute you want to remove:";
$('#img_attr_proceed').val("Image.rmattr");
$('#img_attr_action_desc').html(desc);
$('#image_attributes_dialog').dialog('open');
return false;
}
// Callback to update the information panel tabs and pop it up
function updateImageInfo(request,img){
var img_info = img.IMAGE;
var info_tab = {
title: "Image information",
content:
content:
'<table id="info_img_table" class="info_table">\
<thead>\
<tr><th colspan="2">Image "'+img_info.NAME+'" information</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+img_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">Name</td>\
<td class="value_td">'+img_info.NAME+'</td>\
</tr>\
<tr>\
<td class="key_td">Type</td>\
<td class="value_td">'+OpenNebula.Helper.image_type(img_info.TYPE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Register time</td>\
<td class="value_td">'+pretty_time(img_info.REGTIME)+'</td>\
</tr>\
<tr>\
<td class="key_td">Public</td>\
<td class="value_td">'+(parseInt(img_info.PUBLIC) ? "yes" : "no")+'</td>\
</tr>\
<tr>\
<td class="key_td">Persistent</td>\
<td class="value_td">'+(parseInt(img_info.PERSISTENT) ? "yes" : "no")+'</td>\
</tr>\
<tr>\
<td class="key_td">Source</td>\
<td class="value_td">'+img_info.SOURCE+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("image",img_info.STATE)+'</td>\
</tr>\
</table>'
<thead>\
<tr><th colspan="2">Image "'+img_info.NAME+'" information</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+img_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">Name</td>\
<td class="value_td">'+img_info.NAME+'</td>\
</tr>\
<tr>\
<td class="key_td">Type</td>\
<td class="value_td">'+OpenNebula.Helper.image_type(img_info.TYPE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Register time</td>\
<td class="value_td">'+pretty_time(img_info.REGTIME)+'</td>\
</tr>\
<tr>\
<td class="key_td">Public</td>\
<td class="value_td">'+(parseInt(img_info.PUBLIC) ? "yes" : "no")+'</td>\
</tr>\
<tr>\
<td class="key_td">Persistent</td>\
<td class="value_td">'+(parseInt(img_info.PERSISTENT) ? "yes" : "no")+'</td>\
</tr>\
<tr>\
<td class="key_td">Source</td>\
<td class="value_td">'+img_info.SOURCE+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("image",img_info.STATE)+'</td>\
</tr>\
</table>'
}
var template_tab = {
title: "Image template",
content: '<table id="img_template_table" class="info_table">\
<thead><tr><th colspan="2">Image template</th></tr></thead>'+
prettyPrintJSON(img_info.TEMPLATE)+
'</table>'
<thead><tr><th colspan="2">Image template</th></tr></thead>'+
prettyPrintJSON(img_info.TEMPLATE)+
'</table>'
}
Sunstone.updateInfoPanelTab("image_info_panel","image_info_tab",info_tab);
Sunstone.updateInfoPanelTab("image_info_panel","image_template_tab",template_tab);
Sunstone.popUpInfoPanel("image_info_panel");
}
@ -659,7 +581,7 @@ function updateImageInfo(request,img){
// Prepare the image creation dialog
function setupCreateImageDialog(){
$('div#dialogs').append('<div title="Create Image" id="create_image_dialog"></div>');
//Insert HTML in place
$('#create_image_dialog').html(create_image_tmpl);
@ -667,9 +589,9 @@ function setupCreateImageDialog(){
//Prepare jquery dialog
$('#create_image_dialog').dialog({
autoOpen: false,
modal:true,
width: 520,
autoOpen: false,
modal:true,
width: 520,
height: height
});
@ -795,9 +717,9 @@ function setupCreateImageDialog(){
});
$('#create_image_form_manual').submit(function(){
var template=$('#template',this).val();
var template=$('#template',this).val();
Sunstone.runAction("Image.register",template);
$('#create_image_dialog').dialog('close');
$('#create_image_dialog').dialog('close');
return false;
});
@ -810,43 +732,41 @@ function popUpCreateImageDialog(){
// Set the autorefresh interval for the datatable
function setImageAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_images.fnGetNodes());
var checked = $('input:checked',dataTable_images.fnGetNodes());
var filter = $("#datatable_images_filter input").attr("value");
if (!checked.length && !filter.length){
if (!checked.length && !filter.length){
Sunstone.runAction("Image.autorefresh");
}
},INTERVAL+someTime());
}
},INTERVAL+someTime());
}
//The DOM is ready at this point
$(document).ready(function(){
dataTable_images = $("#datatable_images").dataTable({
dataTable_images = $("#datatable_images").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,3] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [2,3] }
]
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,3] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [2,3,4] }
]
});
dataTable_images.fnClearTable();
addElement([
spinner,
'','','','','','','','',''],dataTable_images);
'','','','','','','','','',''],dataTable_images);
Sunstone.runAction("Image.list");
setupCreateImageDialog();
setupImageAttributesDialogs();
setupTips($('#create_image_dialog'));
setImageAutorefresh();
initCheckAllBoxes(dataTable_images);
tableCheckboxesListener(dataTable_images);
imageInfoListener();
})

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,7 @@ var user_list_json = {};
var dataTable_users;
var users_select="";
var users_tab_content =
var users_tab_content =
'<form id="user_form" action="" action="javascript:alert(\'js error!\');">\
<div class="action_blocks">\
</div>\
@ -29,6 +29,7 @@ var users_tab_content =
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>Name</th>\
<th>Groups</th>\
</tr>\
</thead>\
<tbody id="tbodyusers">\
@ -39,18 +40,18 @@ var users_tab_content =
var create_user_tmpl =
'<form id="create_user_form" action="">\
<fieldset>\
<div>\
<label for="username">Username:</label>\
<input type="text" name="username" id="username" /><br />\
<label for="pass">Password:</label>\
<input type="password" name="pass" id="pass" />\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_user_submit" value="user/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
<div>\
<label for="username">Username:</label>\
<input type="text" name="username" id="username" /><br />\
<label for="pass">Password:</label>\
<input type="password" name="pass" id="pass" />\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_user_submit" value="user/create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>';
@ -62,19 +63,19 @@ var user_actions = {
error: onError,
notify: true
},
"User.create_dialog" : {
type: "custom",
call: popUpCreateUserDialog
},
"User.list" : {
type: "list",
call: OpenNebula.User.list,
callback: updateUsersView,
error: onError
},
"User.refresh" : {
type: "custom",
call: function () {
@ -82,7 +83,7 @@ var user_actions = {
Sunstone.runAction("User.list");
},
},
"User.autorefresh" : {
type: "custom",
call: function(){
@ -91,7 +92,7 @@ var user_actions = {
condition: function(){ uid == 0 },
notify: false
},
"User.delete" : {
type: "multiple",
call: OpenNebula.User.delete,
@ -134,18 +135,46 @@ Sunstone.addMainTab('users_tab',users_tab);
// Returns an array with the values from the user_json ready to be
// added to the dataTable
function userElementArray(user_json){
var user = user_json.USER;
var user = user_json.USER;
if (!user.NAME || user.NAME == {}){
name = "";
} else {
name = user.NAME;
}
return [
'<input type="checkbox" id="user_'+user.ID+'" name="selected_items" value="'+user.ID+'"/>',
user.ID,
name
]
var i = 1;
var groups_str=getGroupName(user.GID)+", ";
var groups_full_str=getGroupName(user.GID)+", ";
var group_field;
if (user.GROUPS.ID){
$.each(user.GROUPS.ID,function() {
if (i<=5) {
groups_str+=getGroupName(this)+", ";
};
groups_full_str+=getGroupName(this)+", ";
i++;
});
if (i>0){
groups_str = groups_str.slice(0, -2);
groups_full_str = groups_str.slice(0, -2);
};
if (i>5){
groups_str+="...";
group_field = '<div class="shortened_info">'+groups_str+'</div><div class="full_info" style="display:none">'+groups_full_str+'</div>';
} else {
group_field=groups_str;
};
}
return [
'<input type="checkbox" id="user_'+user.ID+'" name="selected_items" value="'+user.ID+'"/>',
user.ID,
name,
group_field
]
}
@ -168,8 +197,8 @@ function deleteUserElement(req){
// Callback to add a single user element
function addUserElement(request,user_json){
var element = userElementArray(user_json);
addElement(element,dataTable_users);
var element = userElementArray(user_json);
addElement(element,dataTable_users);
updateUserSelect();
}
@ -179,7 +208,7 @@ function updateUsersView(request,users_list){
var user_list_array = [];
$.each(user_list_json,function(){
user_list_array.push(userElementArray(this));
user_list_array.push(userElementArray(this));
});
updateView(user_list_array,dataTable_users);
updateDashboard("users",user_list_json);
@ -191,31 +220,31 @@ function setupCreateUserDialog(){
$('div#dialogs').append('<div title="Create user" id="create_user_dialog"></div>');
$('#create_user_dialog').html(create_user_tmpl);
//Prepare jquery dialog
$('#create_user_dialog').dialog({
autoOpen: false,
modal:true,
width: 400
});
//Prepare jquery dialog
$('#create_user_dialog').dialog({
autoOpen: false,
modal:true,
width: 400
});
$('#create_user_dialog button').button();
$('#create_user_form').submit(function(){
var user_name=$('#username',this).val();
var user_password=$('#pass',this).val();
var user_name=$('#username',this).val();
var user_password=$('#pass',this).val();
if (!user_name.length && !user_password.length){
notifyError("User name and password must be filled in");
return false;
}
var user_json = { "user" :
{ "name" : user_name,
"password" : user_password }
};
Sunstone.runAction("User.create",user_json);
$('#create_user_dialog').dialog('close');
return false;
});
var user_json = { "user" :
{ "name" : user_name,
"password" : user_password }
};
Sunstone.runAction("User.create",user_json);
$('#create_user_dialog').dialog('close');
return false;
});
}
function popUpCreateUserDialog(){
@ -250,7 +279,7 @@ $(document).ready(function(){
dataTable_users.fnClearTable();
addElement([
spinner,
'',''],dataTable_users);
'','',''],dataTable_users);
Sunstone.runAction("User.list");
@ -259,5 +288,6 @@ $(document).ready(function(){
initCheckAllBoxes(dataTable_users);
tableCheckboxesListener(dataTable_users);
shortenedInfoFields('#datatable_users');
}
})

View File

@ -47,7 +47,7 @@ var vm_graphs = [
}
];
var vms_tab_content =
var vms_tab_content =
'<form id="virtualMachine_list" action="javascript:alert(\'js error!\');">\
<div class="action_blocks">\
</div>\
@ -56,7 +56,8 @@ var vms_tab_content =
<tr>\
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>User</th>\
<th>Owner</th>\
<th>Group</th>\
<th>Name</th>\
<th>Status</th>\
<th>CPU</th>\
@ -73,19 +74,19 @@ var vms_tab_content =
var create_vm_tmpl ='<form id="create_vm_form" action="">\
<fieldset>\
<div>\
<label for="vm_name">VM Name:</label>\
<input type="text" name="vm_name" id="vm_name" /><br />\
<div>\
<label for="vm_name">VM Name:</label>\
<input type="text" name="vm_name" id="vm_name" /><br />\
<label for="template_id">Select template:</label>\
<select id="template_id">\
<select id="template_id">\
</select>\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vm_proceed" value="VM.create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</div>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="create_vm_proceed" value="VM.create">Create</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>';
@ -101,33 +102,33 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.create_dialog" : {
type: "custom",
call: popUpCreateVMDialog,
},
"VM.list" : {
type: "list",
call: OpenNebula.VM.list,
callback: updateVMachinesView,
error: onError
},
"VM.show" : {
type: "single",
call: OpenNebula.VM.show,
callback: updateVMachineElement,
error: onError
},
"VM.showinfo" : {
type: "single",
call: OpenNebula.VM.show,
callback: updateVMInfo,
error: onError
},
"VM.refresh" : {
type: "custom",
call : function (){
@ -135,14 +136,14 @@ var vm_actions = {
Sunstone.runAction("VM.list");
},
},
"VM.autorefresh" : {
type: "custom",
call : function() {
OpenNebula.VM.list({timeout: true, success: updateVMachinesView,error: onError});
},
},
"VM.deploy" : {
type: "multiple",
call: OpenNebula.VM.deploy,
@ -153,7 +154,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.migrate" : {
type: "multiple",
call: OpenNebula.VM.migrate,
@ -164,7 +165,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.livemigrate" : {
type: "multiple",
call: OpenNebula.VM.livemigrate,
@ -175,7 +176,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.hold" : {
type: "multiple",
call: OpenNebula.VM.hold,
@ -186,7 +187,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.release" : {
type: "multiple",
call: OpenNebula.VM.release,
@ -197,7 +198,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.suspend" : {
type: "multiple",
call: OpenNebula.VM.suspend,
@ -208,7 +209,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.resume" : {
type: "multiple",
call: OpenNebula.VM.resume,
@ -219,7 +220,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.stop" : {
type: "multiple",
call: OpenNebula.VM.stop,
@ -230,7 +231,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.restart" : {
type: "multiple",
call: OpenNebula.VM.restart,
@ -241,7 +242,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.resubmit" : {
type: "multiple",
call: OpenNebula.VM.resubmit,
@ -252,7 +253,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.saveasmultiple" : {
type: "custom",
call: function(){
@ -261,12 +262,12 @@ var vm_actions = {
},
elements: function() { return getSelectedNodes(dataTable_vMachines); }
},
"VM.saveas" : {
type: "custom",
call: function(obj) {
OpenNebula.VM.saveas(
{data:obj,
{data:obj,
success: function (req) {
Sunstone.runAction("VM.show",
req.request.data[0][0]);
@ -293,7 +294,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.cancel" : {
type: "multiple",
call: OpenNebula.VM.cancel,
@ -304,7 +305,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.delete" : {
type: "multiple",
call: OpenNebula.VM.delete,
@ -313,7 +314,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.log" : {
type: "single",
call: OpenNebula.VM.log,
@ -337,7 +338,7 @@ var vm_actions = {
onError(request,error_json);
}
},
"VM.startvnc" : {
type: "single",
call: OpenNebula.VM.startvnc,
@ -345,7 +346,7 @@ var vm_actions = {
error: onError,
notify: true
},
"VM.stopvnc" : {
type: "single",
call: OpenNebula.VM.stopvnc,
@ -373,6 +374,26 @@ var vm_actions = {
},
error: onError
},
"VM.chown" : {
type: "multiple",
call: OpenNebula.VM.chown,
callback: function (req) {
Sunstone.runAction("VM.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_vMachines); },
error: onError,
notify: true
},
"VM.chgrp" : {
type: "multiple",
call: OpenNebula.VM.chgrp,
callback: function (req) {
Sunstone.runAction("VM.show",req.request.data[0]);
},
elements: function() { return getSelectedNodes(dataTable_vMachines); },
error: onError,
notify: true
}
}
@ -384,22 +405,38 @@ var vm_buttons = {
img: "/images/Refresh-icon.png",
condition: True
},
"VM.create_dialog" : {
type: "action",
text: "+ New",
condition: True,
alwaysActive: true,
},
"VM.chown" : {
type: "confirm_with_select",
text: "Change owner",
select: function() {return users_select;},
tip: "Select the new owner:",
condition: True
},
"VM.chgrp" : {
type: "confirm_with_select",
text: "Change group",
select: function() {return groups_select;},
tip: "Select the new group:",
condition: True
},
"VM.shutdown" : {
type: "confirm",
text: "Shutdown",
tip: "This will initiate the shutdown process in the selected VMs",
condition: True
},
"action_list" : {
type: "select",
actions: {
@ -422,7 +459,7 @@ var vm_buttons = {
else {return ""}
},
condition: True
},
"VM.livemigrate" : {
type: "confirm_with_select",
@ -432,49 +469,49 @@ var vm_buttons = {
if (hosts_select){return hosts_select}
else {return ""}
},
condition: True
condition: True
},
"VM.hold" : {
type: "confirm",
text: "Hold",
tip: "This will hold selected pending VMs from being deployed",
condition: True
condition: True
},
"VM.release" : {
type: "confirm",
text: "Release",
tip: "This will release held machines",
condition: True
condition: True
},
"VM.suspend" : {
type: "confirm",
text: "Suspend",
tip: "This will suspend selected machines",
condition: True
condition: True
},
"VM.resume" : {
type: "confirm",
text: "Resume",
tip: "This will resume selected stopped or suspended VMs",
condition: True
condition: True
},
"VM.stop" : {
type: "confirm",
text: "Stop",
tip: "This will stop selected VMs",
condition: True
condition: True
},
"VM.restart" : {
type: "confirm",
text: "Restart",
tip: "This will redeploy selected VMs (in UNKNOWN or BOOT state)",
condition: True
condition: True
},
"VM.resubmit" : {
type: "confirm",
text: "Resubmit",
tip: "This will resubmits VMs to PENDING state",
condition: True
condition: True
},
"VM.saveasmultiple" : {
type: "action",
@ -485,12 +522,12 @@ var vm_buttons = {
type: "confirm",
text: "Cancel",
tip: "This will cancel selected VMs",
condition: True
condition: True
}
},
condition: True
},
"VM.delete" : {
type: "confirm",
text: "Delete",
@ -534,142 +571,145 @@ function str_start_time(vm){
// Returns an array formed by the information contained in the vm_json
// and ready to be introduced in a dataTable
function vMachineElementArray(vm_json){
var vm = vm_json.VM;
var vm = vm_json.VM;
var state = OpenNebula.Helper.resource_state("vm",vm.STATE);
if (state == "ACTIVE") {
state = OpenNebula.Helper.resource_state("vm_lcm",vm.LCM_STATE);
}
return [
'<input type="checkbox" id="vm_'+vm.ID+'" name="selected_items" value="'+vm.ID+'"/>',
vm.ID,
vm.USERNAME ? vm.USERNAME : getUserName(vm.UID),
vm.NAME,
state,
vm.CPU,
humanize_size(vm.MEMORY),
vm.HISTORY ? vm.HISTORY.HOSTNAME : "--",
str_start_time(vm),
vncIcon(vm)
]
return [
'<input type="checkbox" id="vm_'+vm.ID+'" name="selected_items" value="'+vm.ID+'"/>',
vm.ID,
getUserName(vm.UID),
getGroupName(vm.GID),
vm.NAME,
state,
vm.CPU,
humanize_size(vm.MEMORY),
vm.HISTORY ? vm.HISTORY.HOSTNAME : "--",
str_start_time(vm),
vncIcon(vm)
];
}
//Creates a listener for the TDs of the VM table
function vMachineInfoListener(){
$('#tbodyvmachines tr').live("click", function(e){
if ($(e.target).is('input') || $(e.target).is('a img')) {return true;}
$('#tbodyvmachines tr').live("click", function(e){
if ($(e.target).is('input') || $(e.target).is('a img')) {return true;}
popDialogLoading();
var aData = dataTable_vMachines.fnGetData(this);
var id = $(aData[0]).val();
var aData = dataTable_vMachines.fnGetData(this);
var id = $(aData[0]).val();
Sunstone.runAction("VM.showinfo",id);
return false;
});
return false;
});
}
// Callback to refresh a single element from the list
function updateVMachineElement(request, vm_json){
var id = vm_json.VM.ID;
var element = vMachineElementArray(vm_json);
updateSingleElement(element,dataTable_vMachines,'#vm_'+id)
var id = vm_json.VM.ID;
var element = vMachineElementArray(vm_json);
updateSingleElement(element,dataTable_vMachines,'#vm_'+id)
}
// Callback to delete a single element from the list
function deleteVMachineElement(req){
deleteElement(dataTable_vMachines,'#vm_'+req.request.data);
deleteElement(dataTable_vMachines,'#vm_'+req.request.data);
}
// Callback to add an element to the list
function addVMachineElement(request,vm_json){
var id = vm_json.VM.ID;
var element = vMachineElementArray(vm_json);
addElement(element,dataTable_vMachines);
var element = vMachineElementArray(vm_json);
addElement(element,dataTable_vMachines);
}
// Callback to refresh the list of Virtual Machines
function updateVMachinesView(request, vmachine_list){
vmachine_list_json = vmachine_list;
var vmachine_list_array = [];
vmachine_list_json = vmachine_list;
var vmachine_list_array = [];
$.each(vmachine_list,function(){
vmachine_list_array.push( vMachineElementArray(this));
});
$.each(vmachine_list,function(){
vmachine_list_array.push( vMachineElementArray(this));
});
updateView(vmachine_list_array,dataTable_vMachines);
updateDashboard("vms",vmachine_list_json);
updateView(vmachine_list_array,dataTable_vMachines);
updateDashboard("vms",vmachine_list_json);
}
// Refreshes the information panel for a VM
function updateVMInfo(request,vm){
var vm_info = vm.VM;
var info_tab = {
var vm_info = vm.VM;
var info_tab = {
title : "VM information",
content: '<table id="info_vm_table" class="info_table">\
<thead>\
<tr><th colspan="2">Virtual Machine information - '+vm_info.NAME+'</th></tr>\
</thead>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+vm_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">Name</td>\
<td class="value_td">'+vm_info.NAME+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("vm",vm_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">LCM State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("vm_lcm",vm_info.LCM_STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Start time</td>\
<td class="value_td">'+pretty_time(vm_info.STIME)+'</td>\
</tr>\
<tr>\
<td class="key_td">Deploy ID</td>\
<td class="value_td">'+(typeof(vm_info.DEPLOY_ID) == "object" ? "-" : vm_info.DEPLOY_ID)+'</td>\
</tr>\
</table>\
<table id="vm_monitoring_table" class="info_table">\
<thead>\
<tr><th colspan="2">Monitoring information</th></tr>\
</thead>\
<tr>\
<td class="key_td">Net_TX</td>\
<td class="value_td">'+vm_info.NET_TX+'</td>\
</tr>\
<tr>\
<td class="key_td">Net_RX</td>\
<td class="value_td">'+vm_info.NET_RX+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Memory</td>\
<td class="value_td">'+humanize_size(vm_info.MEMORY)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU</td>\
<td class="value_td">'+vm_info.CPU+'</td>\
</tr>\
<tr>\
<td class="key_td">VNC Session</td>\
<td class="value_td">'+vncIcon(vm_info)+'</td>\
</tr>\
</table>'
<thead>\
<tr><th colspan="2">Virtual Machine information - '+vm_info.NAME+'</th></tr>\
</thead>\
<tbody>\
<tr>\
<td class="key_td">ID</td>\
<td class="value_td">'+vm_info.ID+'</td>\
</tr>\
<tr>\
<td class="key_td">Name</td>\
<td class="value_td">'+vm_info.NAME+'</td>\
</tr>\
<tr>\
<td class="key_td">State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("vm",vm_info.STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">LCM State</td>\
<td class="value_td">'+OpenNebula.Helper.resource_state("vm_lcm",vm_info.LCM_STATE)+'</td>\
</tr>\
<tr>\
<td class="key_td">Start time</td>\
<td class="value_td">'+pretty_time(vm_info.STIME)+'</td>\
</tr>\
<tr>\
<td class="key_td">Deploy ID</td>\
<td class="value_td">'+(typeof(vm_info.DEPLOY_ID) == "object" ? "-" : vm_info.DEPLOY_ID)+'</td>\
</tr></tbody>\
</table>\
<table id="vm_monitoring_table" class="info_table">\
<thead>\
<tr><th colspan="2">Monitoring information</th></tr>\
</thead>\
<tbody>\
<tr>\
<td class="key_td">Net_TX</td>\
<td class="value_td">'+vm_info.NET_TX+'</td>\
</tr>\
<tr>\
<td class="key_td">Net_RX</td>\
<td class="value_td">'+vm_info.NET_RX+'</td>\
</tr>\
<tr>\
<td class="key_td">Used Memory</td>\
<td class="value_td">'+humanize_size(vm_info.MEMORY)+'</td>\
</tr>\
<tr>\
<td class="key_td">Used CPU</td>\
<td class="value_td">'+vm_info.CPU+'</td>\
</tr>\
<tr>\
<td class="key_td">VNC Session</td>\
<td class="value_td">'+vncIcon(vm_info)+'</td>\
</tr>\
</tbody>\
</table>'
}
var template_tab = {
title: "VM Template",
content: '<table id="vm_template_table" class="info_table">\
<thead><tr><th colspan="2">VM template</th></tr></thead>'+
prettyPrintJSON(vm_info.TEMPLATE)+
'</table>'
<thead><tr><th colspan="2">VM template</th></tr></thead>'+
prettyPrintJSON(vm_info.TEMPLATE)+
'</table>'
}
var log_tab = {
@ -700,30 +740,30 @@ function updateVMInfo(request,vm){
function setupCreateVMDialog(){
$('div#dialogs').append('<div title="Create Virtual Machine" id="create_vm_dialog"></div>');
//Insert HTML in place
$('#create_vm_dialog').html(create_vm_tmpl);
//Insert HTML in place
$('#create_vm_dialog').html(create_vm_tmpl);
//Prepare jquery dialog
$('#create_vm_dialog').dialog({
autoOpen: false,
modal: true,
width: 400
});
//Prepare jquery dialog
$('#create_vm_dialog').dialog({
autoOpen: false,
modal: true,
width: 400
});
$('#create_vm_dialog button').button();
$('#create_vm_dialog #create_vm_proceed').click(function(){
var vm_name = $('#create_vm_form #vm_name').val();
var template_id = $('#create_vm_form #template_id').val();
var vm_json = { vm: { vm_name: vm_name, template_id : template_id }};
Sunstone.runAction("VM.create",vm_json);
$('#create_vm_dialog').dialog('close');
return false;
});
$('#create_vm_dialog #create_vm_cancel').click(function(){
});
}
@ -748,7 +788,7 @@ function setupSaveasDialog(){
</div>\
</fieldset>\
</form>');
$('#saveas_vm_dialog').dialog({
autoOpen:false,
width:600,
@ -756,7 +796,7 @@ function setupSaveasDialog(){
height:350,
resizable:true,
});
$('#saveas_vm_dialog #vm_saveas_proceed').click(function(){
var elems = $('#saveas_vm_dialog #saveas_tabs div.saveas_tab');
var args = [];
@ -765,7 +805,7 @@ function setupSaveasDialog(){
var disk_id = $('#vm_disk_id',this).val();
var image_name = $('#image_name',this).val();
//var type = $('#image_type',this).val();
if (!id.length || !disk_id.length || !image_name.length) {
notifyError("Skipping VM "+id+
". No disk id or image name specified");
@ -784,23 +824,23 @@ function setupSaveasDialog(){
if (args.length > 0){
notifySubmit("VM.saveas",args);
}
$('#saveas_vm_dialog').dialog('close');
$('#saveas_vm_dialog').dialog('close');
return false;
});
$('#saveas_vm_dialog #vm_saveas_cancel').click(function(){
$('#saveas_vm_dialog').dialog('close');
$('#saveas_vm_dialog').dialog('close');
return false;
});
}
function popUpSaveasDialog(elems){
$('#saveas_vm_dialog #saveas_tabs').tabs('destroy');
$('#saveas_vm_dialog #saveas_tabs').empty();
$('#saveas_vm_dialog #saveas_tabs').html('<ul></ul>');
$.each(elems,function(){
var li = '<li><a href="#saveas_tab_'+this+'">VM '+this+'</a></li>'
$('#saveas_vm_dialog #saveas_tabs ul').append(li);
@ -873,12 +913,12 @@ function saveasDisksCallback(req,response){
//Prepares autorefresh
function setVMAutorefresh(){
setInterval(function(){
var checked = $('input:checked',dataTable_vMachines.fnGetNodes());
var checked = $('input:checked',dataTable_vMachines.fnGetNodes());
var filter = $("#datatable_vmachines_filter input").attr("value");
if (!checked.length && !filter.length){
if (!checked.length && !filter.length){
Sunstone.runAction("VM.autorefresh");
}
},INTERVAL+someTime()); //so that not all refreshing is done at the same time
}
},INTERVAL+someTime()); //so that not all refreshing is done at the same time
}
@ -920,7 +960,7 @@ function setupVNC(){
//Append to DOM
$('div#dialogs').append('<div id="vnc_dialog" title="VNC connection"></div>');
$('#vnc_dialog').html('\
<div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">\
<table border=0 width="100%"><tr>\
@ -935,12 +975,12 @@ function setupVNC(){
Canvas not supported.\
</canvas>\
');
$('#sendCtrlAltDelButton').click(function(){
$('#sendCtrlAltDelButton').click(function(){
rfb.sendCtrlAltDel();
return false;
return false;
});
$('#vnc_dialog').dialog({
autoOpen:false,
width:700,
@ -948,13 +988,13 @@ function setupVNC(){
height:500,
resizable:true,
});
$( "#vnc_dialog" ).bind( "dialogclose", function(event, ui) {
var id = $("#vnc_dialog").attr("vm_id");
Sunstone.runAction("VM.stopvnc",id);
});
$('.vnc').live("click",function(){
//Which VM is it?
var id = $(this).attr("vm_id");
@ -976,19 +1016,19 @@ function vncCallback(request,response){
'updateState': updateVNCState});
//fetch things from clicked element host - port - password
vnc_port = response["port"];
//Hopefully this is returning sunstone server address, where
//the proxy is running
vnc_host = window.location.hostname;
vnc_pw = response["password"];
setTimeout(function(){
rfb.connect(vnc_host, vnc_port, vnc_pw);
$('#vnc_dialog').dialog('open');
},4000);
}
function vncIcon(vm){
@ -1003,37 +1043,37 @@ function vncIcon(vm){
gr_icon = '<img src="images/vnc_off.png" alt="VNC Disabled" />';
}
return gr_icon;
}
// At this point the DOM is ready and the sunstone.js ready() has been run.
$(document).ready(function(){
dataTable_vMachines = $("#datatable_vmachines").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"sPaginationType": "full_numbers",
"bAutoWidth":false,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1,9] },
{ "sWidth": "100px", "aTargets": [2] }
]
"bJQueryUI": true,
"bSortClasses": false,
"sPaginationType": "full_numbers",
"bAutoWidth":false,
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0] },
{ "sWidth": "35px", "aTargets": [1,9] },
{ "sWidth": "100px", "aTargets": [2,3,4] }
]
});
dataTable_vMachines.fnClearTable();
addElement([
spinner,
'','','','','','','','',''],dataTable_vMachines);
Sunstone.runAction("VM.list");
'','','','','','','','','',''],dataTable_vMachines);
Sunstone.runAction("VM.list");
setupCreateVMDialog();
setupSaveasDialog();
setVMAutorefresh();
setupVNC();
initCheckAllBoxes(dataTable_vMachines);
tableCheckboxesListener(dataTable_vMachines);
vMachineInfoListener();
})
})

View File

@ -25,7 +25,8 @@ var vnets_tab_content =
<tr>\
<th class="check"><input type="checkbox" class="check_all" value="">All</input></th>\
<th>ID</th>\
<th>User</th>\
<th>Owner</th>\
<th>Group</th>\
<th>Name</th>\
<th>Type</th>\
<th>Bridge</th>\
@ -221,7 +222,7 @@ var vnet_actions = {
"Network.chgrp" : {
type: "multiple",
call: OpenNebula.Network.chown,
call: OpenNebula.Network.chgrp,
callback: function (req) {
Sunstone.runAction("Network.show",req.request.data[0]);
},
@ -305,28 +306,24 @@ Sunstone.addInfoPanel('vnet_info_panel',vnet_info_panel);
//returns an array with the VNET information fetched from the JSON object
function vNetworkElementArray(vn_json){
var network = vn_json.VNET;
var network = vn_json.VNET;
var total_leases = "0";
if (network.TOTAL_LEASES){
total_leases = network.TOTAL_LEASES;
} else if (network.LEASES && network.LEASES.LEASE){
total_leases = network.LEASES.LEASE.length ? network.LEASES.LEASE.length : "1";
}
//Does the JSON bring a username field? Otherwise try
//to get it from the users dataTable
var username = network.USERNAME? network.USERNAME : getUserName(network.UID)
return ['<input type="checkbox" id="vnetwork_'+network.ID+'" name="selected_items" value="'+network.ID+'"/>',
network.ID,
username,
network.NAME,
parseInt(network.TYPE) ? "FIXED" : "RANGED",
network.BRIDGE,
parseInt(network.PUBLIC) ? "yes" : "no",
total_leases ];
network.ID,
getUserName(network.UID),
getGroupName(network.GID),
network.NAME,
parseInt(network.TYPE) ? "FIXED" : "RANGED",
network.BRIDGE,
parseInt(network.PUBLIC) ? "yes" : "no",
total_leases ];
}
@ -346,7 +343,7 @@ function vNetworkInfoListener(){
//updates the vnet select different options
function updateNetworkSelect(){
vnetworks_select=
makeSelectOptions(dataTable_vNetworks,1,3,6,"no",2);
makeSelectOptions(dataTable_vNetworks,1,4,7,"no",2);
//update static selectors:
//in the VM creation dialog
@ -446,134 +443,131 @@ function updateVNetworkInfo(request,vn){
//Prepares the vnet creation dialog
function setupCreateVNetDialog() {
$('div#dialogs').append('<div title="Create Virtual Network" id="create_vn_dialog"></div>');
$('#create_vn_dialog').html(create_vn_tmpl);
//Prepare the jquery-ui dialog. Set style options here.
$('#create_vn_dialog').dialog({
autoOpen: false,
modal: true,
width: 475,
height: 500
});
$('#create_vn_dialog').html(create_vn_tmpl);
//Make the tabs look nice for the creation mode
$('#vn_tabs').tabs();
//Prepare the jquery-ui dialog. Set style options here.
$('#create_vn_dialog').dialog({
autoOpen: false,
modal: true,
width: 475,
height: 500
});
//Make the tabs look nice for the creation mode
$('#vn_tabs').tabs();
$('div#ranged').hide();
$('#fixed_check').click(function(){
$('div#fixed').show();
$('div#ranged').hide();
$('div#fixed').show();
$('div#ranged').hide();
});
$('#ranged_check').click(function(){
$('div#fixed').hide();
$('div#ranged').show();
});
$('#create_vn_dialog button').button();
//When we hit the add lease button...
$('#add_lease').click(function(){
var create_form = $('#create_vn_form_easy'); //this is our scope
//Fetch the interesting values
var lease_ip = $('#leaseip',create_form).val();
var lease_mac = $('#leasemac',create_form).val();
//We don't add anything to the list if there is nothing to add
if (lease_ip == null) {
notifyError("Please provide a lease IP");
return false;
};
$('#create_vn_dialog button').button();
var lease = ""; //contains the HTML to be included in the select box
if (lease_mac == "") {
lease='<option value="' + lease_ip + '">' + lease_ip + '</option>';
} else {
lease='<option value="' +
lease_ip + ',' +
lease_mac + '">' +
lease_ip + ',' + lease_mac +
'</option>';
};
//When we hit the add lease button...
$('#add_lease').click(function(){
var create_form = $('#create_vn_form_easy'); //this is our scope
//We append the HTML into the select box.
$('select#leases').append(lease);
return false;
});
//Fetch the interesting values
var lease_ip = $('#leaseip',create_form).val();
var lease_mac = $('#leasemac',create_form).val();
$('#remove_lease').click(function(){
$('select#leases :selected').remove();
return false;
});
//We don't add anything to the list if there is nothing to add
if (lease_ip == null) {
notifyError("Please provide a lease IP");
return false;
};
//Handle submission of the easy mode
$('#create_vn_form_easy').submit(function(){
//Fetch values
var name = $('#name',this).val();
var lease = ""; //contains the HTML to be included in the select box
if (lease_mac == "") {
lease='<option value="' + lease_ip + '">' + lease_ip + '</option>';
} else {
lease='<option value="' +
lease_ip + ',' +
lease_mac + '">' +
lease_ip + ',' + lease_mac +
'</option>';
};
//We append the HTML into the select box.
$('select#leases').append(lease);
return false;
});
$('#remove_lease').click(function(){
$('select#leases :selected').remove();
return false;
});
//Handle submission of the easy mode
$('#create_vn_form_easy').submit(function(){
//Fetch values
var name = $('#name',this).val();
if (!name.length){
notifyError("Virtual Network name missing!");
return false;
}
var bridge = $('#bridge',this).val();
var type = $('input:checked',this).val();
var bridge = $('#bridge',this).val();
var type = $('input:checked',this).val();
//TODO: Name and bridge provided?!
//TODO: Name and bridge provided?!
var network_json = null;
if (type == "fixed") {
var leases = $('#leases option', this);
var leases_obj=[];
var network_json = null;
if (type == "fixed") {
var leases = $('#leases option', this);
var leases_obj=[];
//for each specified lease we prepare the JSON object
$.each(leases,function(){
leases_obj.push({"ip": $(this).val() });
});
//for each specified lease we prepare the JSON object
$.each(leases,function(){
leases_obj.push({"ip": $(this).val() });
});
//and construct the final data for the request
network_json = {
"vnet" : {
"type" : "FIXED",
"leases" : leases_obj,
"bridge" : bridge,
"name" : name }};
}
else { //type ranged
//and construct the final data for the request
network_json = {
"vnet" : {
"type" : "FIXED",
"leases" : leases_obj,
"bridge" : bridge,
"name" : name }};
}
else { //type ranged
var network_addr = $('#net_address',this).val();
var network_size = $('#net_size',this).val();
if (!network_addr.length){
notifyError("Please provide a network address");
return false;
};
var network_addr = $('#net_address',this).val();
var network_size = $('#net_size',this).val();
if (!network_addr.length){
notifyError("Please provide a network address");
return false;
};
//we form the object for the request
network_json = {
"vnet" : {
"type" : "RANGED",
"bridge" : bridge,
"network_size" : network_size,
"network_address" : network_addr,
"name" : name }
};
};
//we form the object for the request
network_json = {
"vnet" : {
"type" : "RANGED",
"bridge" : bridge,
"network_size" : network_size,
"network_address" : network_addr,
"name" : name }
};
};
//Create the VNetwork.
//Create the VNetwork.
Sunstone.runAction("Network.create",network_json);
$('#create_vn_dialog').dialog('close');
return false;
});
$('#create_vn_dialog').dialog('close');
return false;
});
$('#create_vn_form_manual').submit(function(){
var template=$('#template',this).val();
$('#create_vn_form_manual').submit(function(){
var template=$('#template',this).val();
var vnet_json = {vnet: {vnet_raw: template}};
Sunstone.runAction("Network.create",vnet_json);
$('#create_vn_dialog').dialog('close');
return false;
});
return false;
});
}
function popUpCreateVnetDialog() {
@ -582,44 +576,44 @@ function popUpCreateVnetDialog() {
function setVNetAutorefresh() {
setInterval(function(){
var checked = $('input:checked',dataTable_vNetworks.fnGetNodes());
var checked = $('input:checked',dataTable_vNetworks.fnGetNodes());
var filter = $("#datatable_vnetworks_filter input").attr("value");
if (!checked.length && !filter.length){
Sunstone.runAction("Network.autorefresh");
}
},INTERVAL+someTime());
if (!checked.length && !filter.length){
Sunstone.runAction("Network.autorefresh");
}
},INTERVAL+someTime());
}
//The DOM is ready and the ready() from sunstone.js
//has been executed at this point.
//The DOM is ready and the ready() from sunstone.js
//has been executed at this point.
$(document).ready(function(){
dataTable_vNetworks = $("#datatable_vnetworks").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,4,5,6,7] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [2] }
]
dataTable_vNetworks = $("#datatable_vnetworks").dataTable({
"bJQueryUI": true,
"bSortClasses": false,
"bAutoWidth":false,
"sPaginationType": "full_numbers",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": ["check"] },
{ "sWidth": "60px", "aTargets": [0,5,6,7,8] },
{ "sWidth": "35px", "aTargets": [1] },
{ "sWidth": "100px", "aTargets": [2,3] }
]
});
dataTable_vNetworks.fnClearTable();
addElement([
spinner,
'','','','','','',''],dataTable_vNetworks);
'','','','','','','',''],dataTable_vNetworks);
Sunstone.runAction("Network.list");
setupCreateVNetDialog();
setVNetAutorefresh();
initCheckAllBoxes(dataTable_vNetworks);
tableCheckboxesListener(dataTable_vNetworks);
vNetworkInfoListener();
});

View File

@ -69,13 +69,13 @@ function humanize_size(value) {
//Wrapper to add an element to a dataTable
function addElement(element,data_table){
data_table.fnAddData(element);
data_table.fnAddData(element);
}
//deletes an element with id 'tag' from a dataTable
function deleteElement(data_table,tag){
var tr = $(tag).parents('tr')[0];
data_table.fnDeleteRow(tr);
var tr = $(tag).parents('tr')[0];
data_table.fnDeleteRow(tr);
$('input',data_table).trigger("change");
}
@ -101,11 +101,11 @@ function tableCheckboxesListener(dataTable){
var context = table.parents('form');
var nodes = $('tr',table);
var total_length = nodes.length;
var checked_length = $('input:checked',nodes).length;
var checked_length = $('input:checked',nodes).length;
var last_action_b = $('.last_action_button',context);
//if all elements are checked we check the check-all box
if (total_length == checked_length && total_length != 0){
$('.check_all',dataTable).attr("checked","checked");
@ -125,7 +125,7 @@ function tableCheckboxesListener(dataTable){
$('.top_button, .list_button',context).button("disable");
last_action_b.button("disable");
}
//any case the create dialog buttons should always be enabled.
$('.create_dialog_button',context).button("enable");
$('.alwaysActive',context).button("enable");
@ -136,19 +136,19 @@ function tableCheckboxesListener(dataTable){
// Updates a data_table, with a 2D array containing the new values
// Does a partial redraw, so the filter and pagination are kept
function updateView(item_list,data_table){
if (data_table!=null) {
data_table.fnClearTable();
data_table.fnAddData(item_list);
data_table.fnDraw(false);
};
if (data_table!=null) {
data_table.fnClearTable();
data_table.fnAddData(item_list);
data_table.fnDraw(false);
};
}
//replaces an element with id 'tag' in a dataTable with a new one
function updateSingleElement(element,data_table,tag){
var nodes = data_table.fnGetNodes();
var tr = $(tag,nodes).parents('tr')[0];
var position = data_table.fnGetPosition(tr);
data_table.fnUpdate(element,position,0,false);
var tr = $(tag,nodes).parents('tr')[0];
var position = data_table.fnGetPosition(tr);
data_table.fnUpdate(element,position,0,false);
$('input',data_table).trigger("change");
}
@ -156,11 +156,11 @@ function updateSingleElement(element,data_table,tag){
// Returns an string in the form key=value key=value ...
// Does not explore objects in depth.
function stringJSON(json){
var str = ""
for (field in json) {
str+= field + '=' + json[field] + ' ';
}
return str;
var str = ""
for (field in json) {
str+= field + '=' + json[field] + ' ';
}
return str;
}
//Notifications
@ -223,48 +223,48 @@ function prettyPrintRowJSON(field,value,padding,weight, border_bottom,padding_to
if (typeof value == 'object'){
//name of field row
str += '<tr>\
<td class="key_td" style=\
"padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px;">'
+field+
'</td>\
<td class="value_td" style=\
"border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">\
</td>\
</tr>';
<td class="key_td" style=\
"padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px;">'
+field+
'</td>\
<td class="value_td" style=\
"border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">\
</td>\
</tr>';
//attributes rows
//empty row - prettyprint - empty row
str += '<tr>\
<td class="key_td" style="border-bottom:0"></td>\
<td class="value_td" style="border-bottom:0"></td>\
</tr>' +
prettyPrintJSON(value,padding+25,"normal","0",1) +
'<tr>\
<td class="key_td"></td>\
<td class="value_td"></td>\
</tr>';
} else {
<td class="key_td" style="border-bottom:0"></td>\
<td class="value_td" style="border-bottom:0"></td>\
</tr>' +
prettyPrintJSON(value,padding+25,"normal","0",1) +
'<tr>\
<td class="key_td"></td>\
<td class="value_td"></td>\
</tr>';
} else {
str += '<tr>\
<td class="key_td" style="\
padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
field+
'</td>\
<td class="value_td" style="\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
value+
'</td>\
</tr>';
<td class="key_td" style="\
padding-left:'+padding+'px;\
font-weight:'+weight+';\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
field+
'</td>\
<td class="value_td" style="\
border-bottom:'+border_bottom+';\
padding-top:'+padding_top_bottom+'px;\
padding-bottom:'+padding_top_bottom+'px">'+
value+
'</td>\
</tr>';
};
return str;
@ -273,27 +273,27 @@ function prettyPrintRowJSON(field,value,padding,weight, border_bottom,padding_to
//Add a listener to the check-all box of a datatable, enabling it to
//check and uncheck all the checkboxes of its elements.
function initCheckAllBoxes(datatable){
//not showing nice in that position
//$('.check_all').button({ icons: {primary : "ui-icon-check" },
// text : true});
//small css hack
$('.check_all',datatable).css({"border":"2px"});
$('.check_all',datatable).click(function(){
if ($(this).attr("checked")) {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).attr("checked","checked");
});
//not showing nice in that position
//$('.check_all').button({ icons: {primary : "ui-icon-check" },
// text : true});
} else {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).removeAttr("checked");
});
//small css hack
$('.check_all',datatable).css({"border":"2px"});
$('.check_all',datatable).click(function(){
if ($(this).attr("checked")) {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).attr("checked","checked");
});
} else {
$('tbody input:checkbox',
$(this).parents("table")).each(function(){
$(this).removeAttr("checked");
});
}
$('tbody input:checkbox',$(this).parents("table")).trigger("change");
});
});
}
//standard handling for the server errors on ajax requests.
@ -309,9 +309,9 @@ function onError(request,error_json) {
//redirect to login if unauthenticated
if (error_json.error.http_status=="401") {
window.location.href = "/login";
window.location.href = "/login";
};
if (!message){
notifyError("Cannot contact server: is Sunstone server running and reachable?");
return false;
@ -370,84 +370,81 @@ function onError(request,error_json) {
function waitingNodes(dataTable){
var nodes = dataTable.fnGetData();
for (var i=0;i<nodes.length;i++){
dataTable.fnUpdate(spinner,i,0);
dataTable.fnUpdate(spinner,i,0);
}
};
//given a user ID, returns an string with the user name.
//To do this it finds the user name in the user dataTable. If it is
//not defined then it returns "uid UID".
//TODO not very nice to hardcode a dataTable here...
function getUserName(uid){
var user = uid;
if (typeof(dataTable_users) == "undefined") {
return user;
}
var nodes = dataTable_users.fnGetData();
$.each(nodes,function(){
if (uid == this[1]) {
user = this[2];
return false;
}
});
return user;
return getName(uid,dataTable_users);
}
//Todo
function getGroupName(gid){
return gid;
return getName(gid,dataTable_groups);
}
function getName(id,dataTable){
var name = id;
if (typeof(dataTable) == "undefined") {
return name;
}
var nodes = dataTable.fnGetData();
$.each(nodes,function(){
if (id == this[1]) {
name = this[2];
return false;
}
});
return name;
}
//Replaces all class"tip" divs with an information icon that
//displays the tip information on mouseover.
function setupTips(context){
//For each tip in this context
$('div.tip',context).each(function(){
//store the text
var tip = $(this).html();
//replace the text with an icon and spans
$(this).html('<span class="ui-icon ui-icon-info info_icon"></span>');
$(this).append('<span class="tipspan"></span>');
$(this).append('<span class="ui-icon ui-icon-alert man_icon" />');
//For each tip in this context
$('div.tip',context).each(function(){
//store the text
var tip = $(this).html();
//replace the text with an icon and spans
$(this).html('<span class="ui-icon ui-icon-info info_icon"></span>');
$(this).append('<span class="tipspan"></span>');
//add the text to .tipspan
$('span.tipspan',this).html(tip);
//make sure it is not floating in the wrong place
$(this).parent().append('<div class="clear"></div>');
//hide the text
$('span.tipspan',this).hide();
//When the mouse is hovering on the icon we fadein/out
//the tip text
$('span.info_icon',this).hover(function(e){
var top, left;
top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
$(this).next().css(
{"top":top+"px",
"left":left+"px"});
$(this).next().fadeIn();
},function(){
$(this).next().fadeOut();
});
});
$(this).append('<span class="ui-icon ui-icon-alert man_icon" />');
//add the text to .tipspan
$('span.tipspan',this).html(tip);
//make sure it is not floating in the wrong place
$(this).parent().append('<div class="clear"></div>');
//hide the text
$('span.tipspan',this).hide();
//When the mouse is hovering on the icon we fadein/out
//the tip text
$('span.info_icon',this).hover(function(e){
var top, left;
top = e.pageY - 15;// - $(this).parents('#create_vm_dialog').offset().top - 15;
left = e.pageX + 15;// - $(this).parents('#create_vm_dialog').offset().left;
$(this).next().css(
{"top":top+"px",
"left":left+"px"});
$(this).next().fadeIn();
},function(){
$(this).next().fadeOut();
});
});
}
//returns an array of ids of selected elements in a dataTable
function getSelectedNodes(dataTable){
var selected_nodes = [];
if (dataTable != null){
//Which rows of the datatable are checked?
var nodes = $('input:checked',$('tbody',dataTable));
$.each(nodes,function(){
selected_nodes.push($(this).val());
});
//Which rows of the datatable are checked?
var nodes = $('input:checked',$('tbody',dataTable));
$.each(nodes,function(){
selected_nodes.push($(this).val());
});
}
return selected_nodes;
}
@ -455,10 +452,10 @@ function getSelectedNodes(dataTable){
//returns a HTML string with a select input code generated from
//a dataTable
function makeSelectOptions(dataTable,
id_col,name_col,
status_col,
status_bad,
user_col){
id_col,name_col,
status_col,
status_bad,
user_col){
var nodes = dataTable.fnGetData();
var select = "<option value=\"\">Please select</option>";
var array;
@ -471,8 +468,8 @@ function makeSelectOptions(dataTable,
}
var user = user_col > 0 ? this[user_col] : false;
var isMine = user ? (username == user) || (uid == user) : true;
if (status_col < 0 || (status != status_bad) || isMine ){
select +='<option value="'+id+'">'+name+'</option>';
}
@ -488,7 +485,7 @@ function escapeDoubleQuotes(string){
function generateMonitoringDivs(graphs, id_prefix){
var str = "";
//40% of the width of the screen minus
//40% of the width of the screen minus
//129px (left menu size)
var width = ($(window).width()-129)*45/100;
var id_suffix="";
@ -526,11 +523,11 @@ function plot_graph(data,context,id_prefix,info){
};
var options = {
legend : { show : true,
legend : { show : true,
noColumns: labels_arr.length,
container: $('#legend_'+id_suffix)
},
xaxis : { mode: "time",
xaxis : { mode: "time",
timeformat: "%h:%M"
},
yaxis : { labelWidth: 40,
@ -544,6 +541,75 @@ function plot_graph(data,context,id_prefix,info){
$.plot($('#'+id, context),series,options);
}
//Enables showing full information on this type of fields on
//mouse hover
function shortenedInfoFields(context){
$('.shortened_info',context).live("mouseenter",function(e){
var full_info = $(this).next();
var top,left;
top = (e.pageY-15)+"px";
left = (e.pageX+15)+"px";
full_info.css({"top":top,"left":left});
full_info.fadeIn();
});
$('.shortened_info',context).live("mouseleave",function(e){
$(this).next().fadeOut();
});
}
function setupTemplateUpdateDialog(){
//Append to DOM
$('div#dialogs').append('<div id="template_update_dialog" title="Update template"></div>');
//Put HTML in place
$('#template_update_dialog').html(
'<form action="javascript:alert(\'js error!\');">\
<h3 style="margin-bottom:10px;">Update the template here:</h3>\
<fieldset style="border-top:none;">\
<label for="template_update_select">Select a template:</label>\
<select id="template_update_select" name="template_update_select"></select>\
<div class="clear"></div>\
<textarea id="template_update_textarea" style="width:100%; height:14em;">Select a template</textarea>\
</fieldset>\
<fieldset>\
<div class="form_buttons">\
<button class="button" id="template_update_button" value="">\
Update\
</button>\
<button class="button" type="reset" value="reset">Reset</button>\
</div>\
</fieldset>\
</form>');
$('#template_update_dialog').dialog({
autoOpen:false,
width:700,
modal:true,
height:410,
resizable:false,
});
$('#template_update_dialog button').button();
$('#template_update_dialog #template_update_select').live("change",function(){
var id = $(this).val();
var resource = $('#template_update_dialog #template_update_button').val();
$('#template_update_dialog #template_update_textarea').val("Loading...");
Sunstone.runAction(resource+".fetch_template",id);
});
$('#template_update_dialog #template_update_button').click(function(){
var new_template = $('#template_update_dialog #template_update_textarea').val();
var id = $('#template_update_dialog #template_update_select').val();
var resource = $(this).val();
Sunstone.runAction(resource+".update",id,new_template);
$('#template_update_dialog').dialog('close');
return false;
});
}
//functions that used as true and false conditions for testing mainly
function True(){
return true;

View File

@ -195,39 +195,43 @@ var Sunstone = {
// function with an extraparam if defined.
switch (action_cfg.type){
case "create":
case "register":
call({data:data_arg, success: callback, error:err});
break;
case "single":
case "create":
case "register":
call({data:data_arg, success: callback, error:err});
break;
case "single":
if (extra_param){
call({data:{id:data_arg,extra_param:extra_param}, success: callback,error:err});
} else {
call({data:{id:data_arg}, success: callback,error:err});
break;
case "list":
call({success: callback, error:err});
break;
case "monitor_global":
call({timeout: true, success: callback, error:err, data: {monitor: data_arg}});
break;
case "monitor":
case "monitor_single":
call({timeout: true, success: callback, error:err, data: {id:data_arg, monitor: extra_param}});
break;
};
break;
case "list":
call({success: callback, error:err});
break;
case "monitor_global":
call({timeout: true, success: callback, error:err, data: {monitor: data_arg}});
break;
case "monitor":
case "monitor_single":
call({timeout: true, success: callback, error:err, data: {id:data_arg, monitor: extra_param}});
break;
case "multiple":
//run on the list of nodes that come on the data
$.each(data_arg,function(){
if (extra_param){
call({data:{id:this,extra_param:extra_param}, success: callback, error: err});
} else {
call({data:{id:this}, success: callback, error:err});
}
});
break;
//run on the list of nodes that come on the data
$.each(data_arg,function(){
if (extra_param){
call({data:{id:this,extra_param:extra_param}, success: callback, error: err});
} else {
call({data:{id:this}, success: callback, error:err});
}
});
break;
default:
//This action is complemente handled by the "call" function.
//This action is complemente handled by the "call" function.
//we pass any data if present.
if (data_arg && extra_param) {call(data_arg,extra_param);}
else if (data_arg) {call(data_arg);}
else {call();}
if (data_arg && extra_param) {call(data_arg,extra_param);}
else if (data_arg) {call(data_arg);}
else {call();}
}
//notify submission
if (notify) {
@ -290,6 +294,9 @@ $(document).ready(function(){
//Prepare the standard confirmation dialogs
setupConfirmDialogs();
//This dialog is shared to update templates
setupTemplateUpdateDialog();
//Listen for .action_buttons
//An action buttons runs a predefined action. If it has type

View File

@ -184,6 +184,11 @@ end
##############################################################################
# GET Resource information
##############################################################################
get '/:resource/:id/template' do
@SunstoneServer.get_template(params[:resource], params[:id])
end
get '/:resource/:id' do
@SunstoneServer.get_resource(params[:resource], params[:id])
end