From be1cea51b1d8d376ee3d34a9ac88ea0b578193af Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 13 Dec 2011 14:34:58 +0100 Subject: [PATCH 01/64] Sunstone's multiple VM instantation should act as CLI's when naming the new VMs --- src/sunstone/public/js/plugins/vms-tab.js | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index bdf52bc315..fcb660d857 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -750,20 +750,17 @@ function setupCreateVMDialog(){ if (!template_id.length){ notifyError("You have not selected a template"); return false; - } + }; if (n_times.length){ n_times_int=parseInt(n_times,10); - } + }; - if (n_times_int>1){ - if (!vm_name.length){ - vm_name = $('#template_id option:selected',this).text(); - } - for (var i=0; i< n_times_int; i++){ - Sunstone.runAction("Template.instantiate",template_id,vm_name+"_"+i); - }; - } else { + if (!vm_name.length){ + vm_name = $('#template_id option:selected',this).text(); + }; + + for (var i=0; i< n_times_int; i++){ Sunstone.runAction("Template.instantiate",template_id,vm_name); }; From 176e907c5169d113b9e0009ac00e3267e9463e88 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 20 Dec 2011 12:03:22 +0100 Subject: [PATCH 02/64] Sunstone: add "fw" driver to host creation dialog --- src/sunstone/public/js/plugins/hosts-tab.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index cfbf85d2f7..76e0a9591d 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -83,10 +83,11 @@ var create_host_tmpl =
\ \ \
\
\ From 37d3ed772d59620fd026ae375c71bfa0b4f71772 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 20 Dec 2011 12:03:48 +0100 Subject: [PATCH 03/64] Sunstone: image buses should be downcase in the image creation dialog --- src/sunstone/public/js/plugins/images-tab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index d8fd88bac8..ce879dee85 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -90,8 +90,8 @@ var create_image_tmpl =
\ \ \
Type of disk device to emulate.
\ From 829d32edc233a4b27bcb6ea3e6f366202d3da033 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 20 Dec 2011 12:10:32 +0100 Subject: [PATCH 04/64] Sunstone: do not inform of error when empty save_as dialogs. Rather give an info message that the dialog is ignored. --- src/sunstone/public/js/plugins/vms-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index fcb660d857..74f8ed0ca4 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -812,7 +812,7 @@ function setupSaveasDialog(){ var type = $('#image_type',this).val(); if (!id.length || !disk_id.length || !image_name.length) { - notifyError("Skipping VM "+id+ + notifyMessage("Skipping VM "+id+ ". No disk id or image name specified"); } else { From 5fea81a202e312c29b3a0315475510cf0860625f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 20 Dec 2011 12:45:36 +0100 Subject: [PATCH 05/64] Bug #1022: Fix creation of leases with MAC in Vnetworks --- src/sunstone/public/js/plugins/vnets-tab.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index cb0df258d2..061f740ac6 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -758,7 +758,12 @@ function setupCreateVNetDialog() { //for each specified lease we prepare the JSON object $.each(leases,function(){ - leases_obj.push({"ip": $(this).val() }); + var lease_str = $(this).val().split(","); + if (lease_str[1]) + leases_obj.push({"ip": lease_str[0], + "mac": lease_str[1]}); + else + leases_obj.push({"ip": lease_str[0] }); }); //and construct the final data for the request From cd87c6819ad05414d622d00474d7636434f9a495 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 3 Jan 2012 18:12:31 +0100 Subject: [PATCH 06/64] Feature #992: Improve multiple select for compute creation. --- src/cloud/occi/lib/ui/public/js/plugins/compute.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index aeb9a3ad4a..901c75f30f 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -708,11 +708,11 @@ function popUpCreateVMDialog(){ $('#network_box option,#disk_box option',dialog).click(function(){ var clicked = $(this).attr("clicked"); if (clicked){//unbold, unmark - $(this).text($(this).text().replace(/\*/g,'')); + $(this).text($(this).text().replace(/✓/g,'')); $(this).removeAttr('clicked'); } else {//bold,mark - $(this).text("*"+$(this).text()+"*"); + $(this).text("✓"+$(this).text()); $(this).attr('clicked','clicked'); } return false; From b2b19eb89bad931d2eecc89ae070c2a1417555b5 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 3 Jan 2012 20:18:23 +0100 Subject: [PATCH 07/64] Feature #992: Add text to buttons. Update translations. --- .../occi/lib/ui/public/js/plugins/compute.js | 16 +++++++++------- .../occi/lib/ui/public/js/plugins/network.js | 12 +++++++----- .../occi/lib/ui/public/js/plugins/storage.js | 12 +++++++----- .../occi/lib/ui/public/locale/en_US/en_US.js | 2 ++ .../occi/lib/ui/public/locale/es_ES/es_ES.js | 4 +++- .../locale/generate_translation_template.rb | 2 +- 6 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index 901c75f30f..09ee6c434e 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -93,9 +93,9 @@ var create_vm_tmpl ='
\ \ \
\ - \ + \ + \
\
\ '; @@ -666,19 +666,21 @@ function popUpCreateVMDialog(){ icons: { primary: "ui-icon-check" }, - text: false + text: true }); +/* $('#reset_vm',dialog).button({ icons: { primary: "ui-icon-scissors" }, - text: false + text: true }); +*/ $('.vm_close_dialog_link',dialog).button({ icons: { primary: "ui-icon-closethick" }, - text: false + text: true }); var net_select = makeSelectOptions(dataTable_vNetworks, @@ -706,7 +708,7 @@ function popUpCreateVMDialog(){ }); $('#network_box option,#disk_box option',dialog).click(function(){ - var clicked = $(this).attr("clicked"); + var clicked = $(this).attr('clicked'); if (clicked){//unbold, unmark $(this).text($(this).text().replace(/✓/g,'')); $(this).removeAttr('clicked'); diff --git a/src/cloud/occi/lib/ui/public/js/plugins/network.js b/src/cloud/occi/lib/ui/public/js/plugins/network.js index b4146411ae..a4dc9f6650 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/network.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/network.js @@ -53,9 +53,9 @@ var create_vn_tmpl =
\ \
\ - \ + \ + \
\ \
\ @@ -325,19 +325,21 @@ function popUpCreateVnetDialog() { icons: { primary: "ui-icon-check" }, - text: false + text: true }); +/* $('#reset_vn',dialog).button({ icons: { primary: "ui-icon-scissors" }, text: false }); +*/ $('.vnet_close_dialog_link',dialog).button({ icons: { primary: "ui-icon-closethick" }, - text: false + text: true }); $('#create_vn_form_easy',dialog).submit(function(){ diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index 131c824f24..9ea888355c 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -93,9 +93,9 @@ var create_image_tmpl =
\ -->\
\ - \ + \ + \
\ \
\ @@ -414,19 +414,21 @@ function popUpCreateImageDialog(){ icons: { primary: "ui-icon-check" }, - text: false + text: true }); +/* $('#reset_image',dialog).button({ icons: { primary: "ui-icon-scissors" }, text: false }); +*/ $('.image_close_dialog_link',dialog).button({ icons: { primary: "ui-icon-closethick" }, - text: false + text: true }); setupTips(dialog); diff --git a/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js b/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js index 1d13154a89..26bf137113 100644 --- a/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js +++ b/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js @@ -13,6 +13,7 @@ locale={ "Canvas not supported.":"", "CD-ROM":"", "Changing language":"", + "Close":"", "Community":"", "Compute":"", "Compute resource":"", @@ -21,6 +22,7 @@ locale={ "Configuration":"", "Confirmation of action":"", "CPU":"", + "Create":"", "Create network":"", "Create new compute resource":"", "Create new network resource":"", diff --git a/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js b/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js index 96d30e7769..548e492868 100644 --- a/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js +++ b/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js @@ -13,6 +13,7 @@ locale={ "Canvas not supported.":"Canvas no soportado", "CD-ROM":"CD-ROM", "Changing language":"Cambiando el lenguaje", + "Close":"Cerrar", "Community":"Comunidad", "Compute":"Máquinas Virtuales", "Compute resource":"máquina virtual", @@ -21,6 +22,7 @@ locale={ "Configuration":"Configuración", "Confirmation of action":"Confirmar operación", "CPU":"CPU", + "Create":"Crear", "Create network":"Crear red", "Create new compute resource":"Crear nueva máquina virtual", "Create new network resource":"Crear nueva red", @@ -89,7 +91,7 @@ locale={ "Please select":"Por favor escoja", "Previous action":"Acción anterior", "Public":"Público", - "Public scope of the image":"", + "Public scope of the image":"Imagen pública", "Publish":"Publicar", "Refresh list":"Refrescar lista", "Resume":"Reanudar", diff --git a/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb b/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb index e6adde7429..b3719bd4fa 100755 --- a/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb +++ b/src/cloud/occi/lib/ui/public/locale/generate_translation_template.rb @@ -17,7 +17,7 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -tr_strings = `grep -h -o -R -e 'tr("[[:print:]]*")' ../js/* ../customize/* | cut -d'"' -f 2 | sort -u` +tr_strings = `grep -h -o -R -e 'tr("[[:print:]]*")' ../js/* ../customize/* ../../../../../../sunstone/public/js/sunstone.js ../../../../../../sunstone/public/js/sunstone-util.js | cut -d'"' -f 2 | sort -u` puts "//Translated by" puts 'lang="en_US"' From adbf9dabc50a6854ebcf30f42b112a84c1aff8a7 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 3 Jan 2012 22:20:53 +0100 Subject: [PATCH 08/64] Feature #132: Add reboot action to Sunstone --- src/sunstone/public/js/opennebula.js | 3 +++ src/sunstone/public/js/plugins/vms-tab.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index 0cba8a056e..3956b35752 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -585,6 +585,9 @@ var OpenNebula = { "resubmit": function(params){ OpenNebula.Action.simple_action(params,OpenNebula.VM.resource,"resubmit"); }, + "reboot" : function(params){ + OpenNebula.Action.simple_action(params,OpenNebula.VM.resource,"reboot"); + }, "log": function(params){ OpenNebula.Action.show(params,OpenNebula.VM.resource,"log"); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index a8f8caad3d..de1000a875 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -241,6 +241,15 @@ var vm_actions = { notify: true }, + "VM.reboot" : { + type: "multiple", + call: OpenNebula.VM.reboot, + callback: vmShow, + elements: vmElements, + error: onError, + notify: true + }, + "VM.saveasmultiple" : { type: "custom", call: function(){ @@ -464,6 +473,11 @@ var vm_buttons = { text: tr("Resubmit"), tip: tr("This will resubmits VMs to PENDING state") }, + "VM.reboot" : { + type : "confirm", + text: tr("Reboot"), + tip: tr("This will send a reboot action to running VMs") + }, "VM.saveasmultiple" : { type: "action", text: tr("Save as") From 73ab3a7889c950a4be8b8ccc64020cca733f1eb2 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 4 Jan 2012 13:10:44 +0100 Subject: [PATCH 09/64] Feature #992: File input style fixes --- src/cloud/occi/lib/ui/public/js/plugins/storage.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index 9ea888355c..acc612a091 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -73,11 +73,10 @@ var create_image_tmpl =
'+tr("Type of file system to be built. This can be any value understood by mkfs unix command.")+'
\ \
\ - \ -
\ +
\ +
\
\ - \ -
\ +
\
\ + + @@ -23,7 +25,7 @@
-
+
From 8843c6197a6ceb8acdf57d289149853099faa321 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 4 Jan 2012 15:44:32 +0100 Subject: [PATCH 11/64] Feature #992: Delete elements has no response dataType. Apparently breaks chrome (callback not triggered). --- src/cloud/occi/lib/ui/public/js/occi.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/cloud/occi/lib/ui/public/js/occi.js b/src/cloud/occi/lib/ui/public/js/occi.js index 4e28a5138b..632223d24b 100644 --- a/src/cloud/occi/lib/ui/public/js/occi.js +++ b/src/cloud/occi/lib/ui/public/js/occi.js @@ -235,7 +235,6 @@ var OCCI = { $.ajax({ url: resource.toLowerCase() + "/" + id, type: "DELETE", - dataType: "xml ONEjson", success: function(){ return callback ? callback(request) : null; }, From b6190cdf3ec7558fdc32b4e83a5182ba2c1575b1 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 4 Jan 2012 16:49:15 +0100 Subject: [PATCH 12/64] Fixes in network plugins. In SelfService add missing network information (address, size). Fix some html syntax in SelfService/Sunstone plugins. --- .../occi/lib/ui/public/js/plugins/network.js | 19 ++++++++++++++++++- .../occi/lib/ui/public/js/plugins/storage.js | 4 ++-- src/sunstone/public/js/plugins/vnets-tab.js | 4 ++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/network.js b/src/cloud/occi/lib/ui/public/js/plugins/network.js index a4dc9f6650..d66d45d1f8 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/network.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/network.js @@ -290,11 +290,28 @@ function updateVNetworkInfo(request,vn){ \ '+tr("ID")+'\ '+vn_info.ID+'\ - \ + \ \ '+tr("Name")+'\ '+vn_info.NAME+'\ + \ \ + '+tr("Used leases")+'\ + '+vn_info.USED_LEASES+'\ + '; + + if (vn_info.ADDRESS){ + info_tab_content += '\ + \ + '+tr("Address")+'\ + '+vn_info.ADDRESS+'\ + \ + \ + '+tr("Size")+'\ + '+vn_info.SIZE+'\ + '; + }; + info_tab_content += '\ \
\
'; diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index acc612a091..7a4b3be704 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -366,14 +366,14 @@ function updateImageInfo(request,img){ '+img_info.NAME+'\ \ \ - '+tr("Name")+'\ + '+tr("Description")+'\ '+img_info.DESCRIPTION+'\ \ \ '+tr("Type")+'\ '+OCCI.Helper.image_type(img_info.TYPE)+'\ \ - \ + \ '+tr("Persistent")+'\ \ \ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index b227fd2b64..5b445f32a7 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -487,11 +487,11 @@ function updateVNetworkInfo(request,vn){ \ '+tr("ID")+'\ '+vn_info.ID+'\ - \ + \ \ '+tr("Name")+'\ '+vn_info.NAME+'\ - \ + \ \ '+tr("Owner")+'\ '+vn_info.UNAME+'\ From f14c08feb41980dd21617d842e42ba198f4f85f9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 5 Jan 2012 18:16:46 +0100 Subject: [PATCH 13/64] Sunstone: Fix IP_end parameter when creating VNet --- src/sunstone/public/js/plugins/vnets-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 5b445f32a7..5e3ba99707 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -802,7 +802,7 @@ function setupCreateVNetDialog() { if (ip_start.length) network_json["vnet"]["ip_start"] = ip_start; if (ip_end.length) - network_json["vnet"]["ip_start"] = ip_end; + network_json["vnet"]["ip_end"] = ip_end; }; }; From 96b80be337dd4809faa1bfc070cec6dad56c8f1e Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 11 Jan 2012 16:13:12 +0100 Subject: [PATCH 14/64] Small fixes mostly submitted by VIVOSS & OI As a result, update default translation templates. --- src/cloud/occi/lib/ui/public/js/locale.js | 20 ++++++++++--------- .../occi/lib/ui/public/locale/en_US/en_US.js | 3 +++ src/sunstone/public/js/locale.js | 20 ++++++++++--------- src/sunstone/public/js/plugins/users-tab.js | 6 +++--- src/sunstone/public/js/plugins/vms-tab.js | 2 +- src/sunstone/public/js/plugins/vnets-tab.js | 4 ++-- src/sunstone/public/locale/en_US/en_US.js | 3 +++ 7 files changed, 34 insertions(+), 24 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/locale.js b/src/cloud/occi/lib/ui/public/js/locale.js index bfec7d8f4e..5d0787c62e 100644 --- a/src/cloud/occi/lib/ui/public/js/locale.js +++ b/src/cloud/occi/lib/ui/public/js/locale.js @@ -30,16 +30,18 @@ function tr(str){ //Pops up loading new language dialog. Retrieves the user template, updates the LANG variable. //Updates template and session configuration and reloads the view. function setLang(lang_str){ - var dialog = $('
'+tr("Loading new language... please wait")+' '+spinner+'
').dialog({ - draggable:false, - modal:true, - resizable:false, - buttons:{}, - width: 460, - minHeight: 50 + var dialog = $('
'+ + tr("Loading new language... please wait")+ + ' '+spinner+'
').dialog({ + draggable:false, + modal:true, + resizable:false, + buttons:{}, + width: 460, + minHeight: 50 + }); - }); - if (('localStorage' in window) && (window['localStorage'] !== null)){ localStorage['lang']=lang_str; }; diff --git a/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js b/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js index d36fd78cb4..af44b104e6 100644 --- a/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js +++ b/src/cloud/occi/lib/ui/public/locale/en_US/en_US.js @@ -5,6 +5,7 @@ locale={ "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.":"", "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.":"", "Additionally, you can take a \'snapshot\' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.":"", + "Address":"", "Add storage":"", "All":"", "are mandatory":"", @@ -59,6 +60,7 @@ locale={ "IP":"", "Language":"", "Loading":"", + "Loading new language... please wait":"", "MAC":"", "Make non persistent":"", "Make persistent":"", @@ -135,6 +137,7 @@ locale={ "Unpublish":"", "Update":"", "Update template":"", + "Used leases":"", "Useful links":"", "Virtual Machine information":"", "virtual machines":"", diff --git a/src/sunstone/public/js/locale.js b/src/sunstone/public/js/locale.js index d5b1e970c5..6c3b21ac0e 100644 --- a/src/sunstone/public/js/locale.js +++ b/src/sunstone/public/js/locale.js @@ -31,15 +31,17 @@ function tr(str){ //Updates template and session configuration and reloads the view. function setLang(lang_str){ var lang_tmp=""; - var dialog = $('
'+tr("Loading new language... please wait")+' '+spinner+'
').dialog({ - draggable:false, - modal:true, - resizable:false, - buttons:{}, - width: 460, - minHeight: 50 - - }); + var dialog = $('
'+ + tr("Loading new language... please wait")+ + ' '+spinner+'
').dialog({ + draggable:false, + modal:true, + resizable:false, + buttons:{}, + width: 460, + minHeight: 50 + }); var updateUserTemplate = function(request,user_json){ var template = user_json.USER.TEMPLATE; diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 5ce9543a75..e702a0d0b4 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -60,8 +60,8 @@ var create_user_tmpl = \
\
\ - \ - \ + \ + \
\
\ '; @@ -283,7 +283,7 @@ var user_buttons = { // }, "User.delete" : { type: "action", - text: "Delete" + text: tr("Delete") } } diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index de1000a875..4a08614243 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -882,7 +882,7 @@ function popUpSaveasDialog(elems){ \ \ \ - \ \
\ \ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 5e3ba99707..8749c8ebc7 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -365,7 +365,7 @@ var vnet_buttons = { "Network.chgrp" : { type: "confirm_with_select", - text: "Change group", + text: tr("Change group"), select: groups_sel, tip: tr("Select the new group")+":", condition: mustBeAdmin, @@ -502,7 +502,7 @@ function updateVNetworkInfo(request,vn){ \ \ '+tr("Public")+'\ - '+(parseInt(vn_info.PUBLIC) ? "yes" : "no" )+'\ + '+(parseInt(vn_info.PUBLIC) ? tr("yes") : tr("no") )+'\ \ \ '+tr("Physical device")+'\ diff --git a/src/sunstone/public/locale/en_US/en_US.js b/src/sunstone/public/locale/en_US/en_US.js index 1c0df1f1fe..223055d2a0 100644 --- a/src/sunstone/public/locale/en_US/en_US.js +++ b/src/sunstone/public/locale/en_US/en_US.js @@ -198,6 +198,7 @@ locale={ "Listen IP":"", "Live migrate":"", "Loading":"", + "Loading new language... please wait":"", "MAC":"", "Make non persistent":"", "Make persistent":"", @@ -298,6 +299,7 @@ locale={ "Raw":"", "Raw data to be passed directly to the hypervisor":"", "Read only":"", + "Reboot":"", "Refresh list":"", "Register time":"", "Registration time":"", @@ -390,6 +392,7 @@ locale={ "This will release held machines":"", "This will resubmits VMs to PENDING state":"", "This will resume selected stopped or suspended VMs":"", + "This will send a reboot action to running VMs":"", "This will suspend selected machines":"", "TM MAD":"", "total":"", From 5e638be122f4b1b0a4efce0113813f6be254ffee Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 11 Jan 2012 16:17:58 +0100 Subject: [PATCH 15/64] Update SelfService Spanish translation --- src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js b/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js index 49d91652f2..bc98663351 100644 --- a/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js +++ b/src/cloud/occi/lib/ui/public/locale/es_ES/es_ES.js @@ -5,6 +5,7 @@ locale={ "Additionally, OpenNebula Self-Service allows easy customization of the interface (e.g. this text) and brings multi-language support.":"Además, OpenNebula Self-Service permite una fácil personalización de la interfaz (por ejemplo, de este mismo texto) y viene con soporte para múltiples lenguajes.", "Additionally, you can run several operations on defined storages, such as defining their persistance. Persistent images can only be used by 1 virtual machine, and the changes made by it have effect on the base image. Non-persistent images are cloned before being used in a Virtual Machine, therefore changes are lost unless a snapshot is taken prior to Virtual Machine shutdown.":"Además, puede ejecutar varias operaciones en los almacenamientos presentes, como definir su persistencia. Las imágenes persistentes sólo pueden ser usadas por 1 máquina virtual, y los cambios realizados por ella tiene efecto en la imágen base. Las imágenes no persistentes son clonadas antes de ser utilizadas en una máquina virtual, por tanto los cambios se pierden a menos que se tome una instantánea antes de apagar la máquina virtual.", "Additionally, you can take a 'snapshot' of the storage attached to these resources. They will be saved as new resources, visible from the Storage view and re-usable.":"Además, puede tomar una 'instantánea' de los almacenamientos asociado a estos recursos. Ésta será salvaguardada como un nuevo recurso, visible y reutilizable desde la vista de almacenamientos.", + "Address":"Dirección", "Add storage":"Añadir almacenamiento", "All":"Todos", "are mandatory":"son obligatorios", @@ -59,6 +60,7 @@ locale={ "IP":"IP", "Language":"Lenguaje", "Loading":"Cargando", + "Loading new language... please wait":"Cargando nuevo lenguaje... espere, por favor", "MAC":"MAC", "Make non persistent":"Hacer no persistente", "Make persistent":"Hacer persistente", @@ -135,6 +137,7 @@ locale={ "Unpublish":"Despublicar", "Update":"Actualizar", "Update template":"Actualizar plantilla", + "Used leases":"Leases usados", "Useful links":"Enlances útiles", "Virtual Machine information":"Información de máquina virtual", "virtual machines":"máquinas virtuales", From d24f6b4374467f56c6a948e56226536c11c57ac9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 11 Jan 2012 16:18:34 +0100 Subject: [PATCH 16/64] Upgrade Sunstone russian translation for release 3.2. Translation provided by VIVOSS & OI --- src/sunstone/public/locale/ru/ru.js | 991 ++++++++++++++-------------- 1 file changed, 511 insertions(+), 480 deletions(-) diff --git a/src/sunstone/public/locale/ru/ru.js b/src/sunstone/public/locale/ru/ru.js index 1c0df1f1fe..5707fcb166 100644 --- a/src/sunstone/public/locale/ru/ru.js +++ b/src/sunstone/public/locale/ru/ru.js @@ -1,482 +1,513 @@ -//Translated by -lang="en_US" -datatable_lang="" +//Translated by CJSC "VIVOSS and OI", 2011 +//Переведено ЗАО «ВИВОСС и ОИ», 2011 +lang="ru" +datatable_lang="ru_datatable.txt" locale={ - "Accept (default)":"", - "Acl":"", - "ACL Rules":"", - "ACLs":"", - "ACL String preview":"", - "ACPI":"", - "Add":"", - "Add context variables":"", - "Add custom variables":"", - "Add disk/image":"", - "Add disks/images":"", - "Add Graphics":"", - "Add Hypervisor raw options":"", - "Add inputs":"", - "Add lease":"", - "Add network":"", - "Add placement options":"", - "Advanced mode":"", - "Affected resources":"", - "All":"", - "Allowed operations":"", - "Amount of RAM required for the VM, in Megabytes.":"", - "Applies to":"", - "Architecture":"", - "are mandatory":"", - "Arguments for the booting kernel":"", - "Authentication":"", - "Authentication driver":"", - "Block":"", - "Boolean expression that rules out provisioning hosts from list of machines suitable to run this VM":"", - "Boot":"", - "Boot device type":"", - "Bootloader":"", - "Boot method":"", - "Boot/OS options":"", - "Bridge":"", - "Bus":"", - "Cancel":"", - "Cannot contact server: is it running and reachable?":"", - "Canvas not supported.":"", - "Capacity":"", - "Capacity options":"", - "cdrom":"", - "CD-ROM":"", - "Change":"", - "Change authentication":"", - "Change group":"", - "Change owner":"", - "Change password":"", - "Changing language":"", - "Clone":"", - "Clone this image":"", - "Community":"", - "Configuration":"", - "Confirmation of action":"", - "Context":"", - "Context variable name and value must be filled in":"", - "Core":"", - "CPU":"", - "CPU architecture to virtualization":"", - "CPU Monitoring information":"", - "CPU Use":"", - "Create":"", - "Create ACL":"", - "Create an empty datablock":"", - "Create group":"", - "Create host":"", - "Create Image":"", - "Create user":"", - "Create Virtual Machine":"", - "Create Virtual Network":"", - "Create VM Template":"", - "Current disks":"", - "Current inputs":"", - "Current leases":"", - "Current NICs":"", - "Current variables":"", - "Custom attribute name and value must be filled in":"", - "Custom attributes":"", - "Custom variable name and value must be filled in":"", - "Custom variables":"", - "Dashboard":"", - "Data":"", - "Datablock":"", - "Default":"", - "Default (current image type)":"", - "Define a subnet by IP range":"", - "Delete":"", - "Delete host":"", - "Deploy":"", - "Deploy ID":"", - "Deploy # VMs":"", - "Description":"", - "Device prefix":"", - "Device to be mounted as root":"", - "Device to map image disk. If set, it will overwrite the default device mapping":"", - "Disable":"", - "disabled":"", - "Disallow access to the VM through the specified ports in the TCP protocol":"", - "Disallow access to the VM through the specified ports in the UDP protocol":"", - "Disk":"", - "Disk file location path or URL":"", - "disk id":"", - "Disks":"", - "Disk type":"", - "Documentation":"", - "Do you want to proceed?":"", - "Driver":"", - "Driver default":"", - "Drivers":"", - "Drop":"", - "Dummy":"", - "EC2":"", - "Enable":"", - "English":"", - "Error":"", - "failed":"", - "fd":"", - "Features":"", - "Fields marked with":"", - "File":"", - "Filesystem type":"", - "Filesystem type for the fs images":"", - "Fill in a new password":"", - "Fixed network":"", - "Floppy":"", - "Fold / Unfold all sections":"", - "Format":"", - "FS":"", - "FS type":"", - "Get Information":"", - "Get Pool of my/group\'s resources":"", - "Get Pool of resources":"", - "Graphics":"", - "Graphics type":"", - "Group":"", - "Group ":"", - "Group name":"", - "Groups":"", - "Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.":"", - "hd":"", - "Historical monitoring information":"", - "hold":"", - "Hold":"", - "Hold lease":"", - "Host":"", - "Host information":"", - "Hostname":"", - "Host name missing!":"", - "Host parameters":"", - "Hosts":"", - "Hosts CPU":"", - "Host shares":"", - "Hosts memory":"", - "Hosts (total/active)":"", - "Host template":"", - "Human readable description of the image for other users.":"", - "HW address associated with the network interface":"", - "Icmp":"", - "ICMP policy":"", - "id":"", - "ID":"", - "IDE":"", - "Image":"", - "Image cannot be public and persistent":"", - "Image information":"", - "Image name":"", - "Images":"", - "Images (total/public)":"", - "Image template":"", - "IM MAD":"", - "Info":"", - "information":"", - "Information":"", - "Information Manager":"", - "Initrd":"", - "Inputs":"", - "Instantiate":"", - "IP":"", - "IP End":"", - "IP Start":"", - "IP to listen on":"", - "Kernel":"", - "Kernel commands":"", - "Keyboard configuration locale to use in the VNC display":"", - "Keymap":"", - "KVM":"", - "Language":"", - "LCM State":"", - "Lease IP":"", - "Lease MAC (opt):":"", - "Lease management":"", - "Leases information":"", - "Listen IP":"", - "Live migrate":"", - "Loading":"", - "MAC":"", - "Make non persistent":"", - "Make persistent":"", - "Manage":"", - "Manual":"", - "Max Mem":"", - "Memory":"", - "Memory monitoring information":"", - "Memory use":"", - "Migrate":"", - "Model":"", - "Monitoring information":"", - "Mount image as read-only":"", - "Mouse":"", - "Name":"", - "Name for the context variable":"", - "Name for the custom variable":"", - "Name for the tun device created for the VM":"", - "Name of a shell script to be executed after creating the tun device for the VM":"", - "Name of the bridge the network device is going to be attached to":"", - "Name of the image to use":"", - "Name of the network to attach this device":"", - "Name that the Image will get. Every image must have a unique name.":"", - "Name that the VM will get for description purposes. If NAME is not supplied a name generated by one will be in the form of one-<VID>.":"", - "Net_RX":"", - "Net_TX":"", - "network":"", - "Network":"", - "Network Address":"", - "Network is unreachable: is OpenNebula running?":"", - "Network mask":"", - "Network Mask":"", - "Network reception":"", - "Network transmission":"", - "Network type":"", - "New":"", - "+ New":"", - "+ New Group":"", - "New password":"", - "No":"", - "No disk id or image name specified":"", - "No disks defined":"", - "No leases to show":"", - "None":"", - "Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.":"", - "OK":"", - "Open VNC Session":"", - "Optional, please select":"", - "OS":"", - "OS and Boot options":"", - "Owned by group":"", - "Owner":"", - "PAE":"", - "Password":"", - "Password for the VNC server":"", - "Path":"", - "Path to the bootloader executable":"", - "Path to the initrd image":"", - "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.":"", - "Path to the OS kernel to boot the image":"", - "Path vs. source":"", - "Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.":"", - "Permits access to the VM only through the specified ports in the TCP protocol":"", - "Permits access to the VM only through the specified ports in the UDP protocol":"", - "Persistence of the image":"", - "Persistent":"", - "Physical address extension mode allows 32-bit guests to address more than 4 GB of memory":"", - "Physical device":"", - "Placement":"", - "Please choose":"", - "Please, choose and modify the image you want to update":"", - "Please, choose and modify the template you want to update":"", - "Please, choose and modify the virtual network you want to update":"", - "Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.":"", - "Please choose the new type of authentication for the selected users":"", - "Please provide a lease IP":"", - "Please provide a network address":"", - "Please provide a resource ID for the resource(s) in this rule":"", - "Please select":"", - "Please select at least one resource":"", - "Please specify to who this ACL applies":"", - "Port":"", - "Port blacklist":"", - "Port for the VNC server":"", - "Port whitelist":"", - "Predefined":"", - "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”).":"", - "Previous action":"", - "Provide a path":"", - "Provide a source":"", - "PS2":"", - "Public":"", - "Public scope of the image":"", - "Publish":"", - "Quickstart":"", - "Ranged network":"", - "Rank":"", - "Raw":"", - "Raw data to be passed directly to the hypervisor":"", - "Read only":"", - "Refresh list":"", - "Register time":"", - "Registration time":"", - "release":"", - "Release":"", - "Remove selected":"", - "Request an specific IP from the Network":"", - "Requirements":"", - "Reset":"", - "Resource ID":"", - "Resource ID / Owned by":"", - "Resource subset":"", - "Restart":"", - "Resubmit":"", - "Resume":"", - "Retrieving":"", - "Root":"", - "running":"", - "Running VMs":"", - "Running #VMS":"", - "Russian":"", - "Save":"", - "Save as":"", - "Saveas for VM with ID":"", - "Save this image after shutting down the VM":"", - "Script":"", - "SCSI":"", - "SDL":"", - "Select a network":"", - "Select an image":"", - "Select a template":"", - "Select boot method":"", - "Select disk":"", - "Select template":"", - "Select the new group":"", - "Select the new owner":"", - "Server (Cipher)":"", - "Server (x509)":"", - "Setup Networks":"", - "Shared":"", - "Shutdown":"", - "Sign out":"", - "Size":"", - "Size in MB":"", - "Size (Mb)":"", - "Size of the datablock in MB.":"", - "Skipping VM ":"", - "Source":"", - "Source to be used in the DISK attribute. Useful for not file-based images.":"", - "Specific ID":"", - "Specific image mapping driver. KVM: raw, qcow2. XEN: tap:aio, file:":"", - "Specific image mapping driver. KVM: raw, qcow2. Xen:tap:aio:, file:. VMware unsupported":"", - "SSH":"", - "Start time":"", - "Start Time":"", - "State":"", - "Status":"", - "Stop":"", - "Submitted":"", - "Summary of resources":"", - "Sunstone UI Configuration":"", - "Support":"", - "Suspend":"", - "Swap":"", - "Tablet":"", - "Target":"", - "Tcp black ports":"", - "Tcp firewall mode":"", - "Tcp white ports":"", - "Template":"", - "Template information":"", - "Templates":"", - "Template updated correctly":"", - "There are mandatory fields missing in the capacity section":"", - "There are mandatory fields missing in the OS Boot options section":"", - "There are mandatory parameters missing":"", - "There are mandatory parameters missing in this section":"", - "This field sets which attribute will be used to sort the suitable hosts for this VM. Basically, it defines which hosts are more suitable than others":"", - "This rule applies to":"", - "This will cancel selected VMs":"", - "This will change the main group of the selected users. Select the new group":"", - "This will change the password for the selected users":"", - "This will delete the selected VMs from the database":"", - "This will deploy the selected VMs on the chosen host":"", - "This will hold selected pending VMs from being deployed":"", - "This will initiate the shutdown process in the selected VMs":"", - "This will live-migrate the selected VMs to the chosen host":"", - "This will migrate the selected VMs to the chosen host":"", - "This will redeploy selected VMs (in UNKNOWN or BOOT state)":"", - "This will release held machines":"", - "This will resubmits VMs to PENDING state":"", - "This will resume selected stopped or suspended VMs":"", - "This will suspend selected machines":"", - "TM MAD":"", - "total":"", - "Total Leases":"", - "Total VM count":"", - "Total VM CPU":"", - "Total VM Memory":"", - "Transfer Manager":"", - "Type":"", - "Type of disk device to emulate.":"", - "Type of disk device to emulate: ide, scsi":"", - "Type of file system to be built. This can be any value understood by mkfs unix command.":"", - "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).":"", - "Udp black ports":"", - "Udp firewall mode":"", - "Udp white ports":"", - "Unauthorized":"", - "Unpublish":"", - "Update":"", - "Update a template":"", - "Update image template":"", - "Update network template":"", - "Update template":"", - "USB":"", - "Use":"", - "Used by VM":"", - "Used CPU":"", - "Used CPU (allocated)":"", - "Used CPU (real)":"", - "Used Mem (allocated)":"", - "Used Memory":"", - "Used Mem (real)":"", - "Useful for power management, for example, normally required for graceful shutdown to work":"", - "User":"", - "Username":"", - "User name and password must be filled in":"", - "Users":"", - "Value":"", - "Value of the context variable":"", - "Value of the custom variable":"", - "VCPU":"", - "Virtio":"", - "Virtio (KVM)":"", - "Virtualization Manager":"", - "Virtual Machine information":"", - "Virtual Machines":"", - "Virtual Network":"", - "Virtual network information":"", - "Virtual Network information":"", - "Virtual Network name missing!":"", - "Virtual Networks":"", - "Virtual Networks (total/public)":"", - "Virtual Network template (attributes)":"", - "VM information":"", - "VM Instance":"", - "VM Instances":"", - "VM log":"", - "VM MAD":"", - "VM Name":"", - "VM Network stats":"", - "#VMS":"", - "VM Save As":"", - "VM template":"", - "VM Template":"", - "VM Templates":"", - "VM Templates (total/public)":"", - "VNC":"", - "VNC Access":"", - "VNC connection":"", - "VNC Disabled":"", - "VNC Session":"", - "VNET ID":"", - "VN MAD":"", - "Welcome":"", - "Wizard":"", - "Wizard KVM":"", - "Wizard VMware":"", - "Wizard XEN":"", - "Write the image template here":"", - "Write the Virtual Machine template here":"", - "Write the Virtual Network template here":"", - "x509":"", - "XEN":"", - "Xen templates must specify a boot method":"", - "yes":"", - "Yes":"", - "You have not selected a template":"", - "You have to confirm this action.":"", - "You need to select something.":"", + "Accept (default)":"Принять (по умолчанию)", + "Acl":"Правило контроля доступа", + "ACL Rules":"Правила контроля доступа", + "ACLs":"Списки контроля", + "ACL String preview":"Строка, задающая правило", + "ACPI":"ACPI", + "Add":"Добавить", + "Add context variables":"Добавить контекстные переменные", + "Add custom variables":"Добавить пользовательские переменные", + "Add disk/image":"Добавить диск/образ", + "Add disks/images":"Добавить диски/образы", + "Add Graphics":"Добавить средства графического доступа", + "Add Hypervisor raw options":"Добавить исходные опции гипервизора", + "Add inputs":"Добавить устройства ввода", + "Add lease":"Добавить адрес", + "Add network":"Добавить сеть", + "Add placement options":"Добавить опции размещения", + "Admin":"Администрирование", + "Administrate":"Администрирование", + "Advanced mode":"Расширенный режим", + "Affected resources":"Затрагиваемые ресурсы", + "All":"Все", + "Allowed operations":"Разрешенные действия", + "Amount of RAM required for the VM, in Megabytes.":"Объем ОЗУ (в МБ), необходимый для ВМ.", + "Applies to":"Применено к", + "Architecture":"Архитектура", + "are mandatory":", обязательны к заполнению", + "Arguments for the booting kernel":"Параметры для загрузки ядра", + "Authentication":"Способ аутентификации", + "Authentication driver":"Драйвер аутентификации", + "Block":"Block", + "Boolean expression that rules out provisioning hosts from list of machines suitable to run this VM":"Логическое выражение, исключающее элементы из списка узлов, подходящих для запуска данной ВМ", + "Boot":"Загрузка", + "Boot device type":"Тип устройства загрузки", + "Bootloader":"Загрузчик", + "Boot method":"Метод загрузки", + "Boot/OS options":"Загрузка и тип ОС", + "Bridge":"Шлюз", + "Bus":"Тип шины", + "Cancel":"Отменить", + "Cannot contact server: is it running and reachable?":"Не удается установить соединение с сервером. Проверьте его доступность и/или удостоверьтесь в том, что он запущен.", + "Canvas not supported.":"Canvas не поддерживается.", + "Capacity":"Производительность", + "Capacity options":"Настройки производительности", + "cdrom":"cdrom", + "CD-ROM":"CD-ROM", + "Change":"Сменить", + "Change authentication":"Сменить способ аутентификации", + "Change group":"Сменить группу", + "Change owner":"Сменить владельца", + "Change password":"Сменить пароль", + "Changing language":"Смена языка интерфейса", + "Clone":"Клонировать", + "Clone this image":"Клонировать образ", + "Community":"Сообщество OpenNebula", + "Configuration":"Интерфейс", + "Confirmation of action":"Смена значения", + "Context":"Контекст", + "Context variable name and value must be filled in":"Поля «Имя переменной» и «Значение» должны быть заполнены", + "Core":"Core", + "CPU":"ЦП", + "CPU architecture to virtualization":"Архитектура ЦП для виртуализации", + "CPU Monitoring information":"Мониторинг ЦП", + "CPU Use":"Использование ЦП", + "Create":"Создать", + "Create ACL":"Создать правило контроля", + "Create an empty datablock":"Создать пустой блок данных", + "Create group":"Создать группу", + "Create host":"Укажите параметры нового узла", + "Create Image":"Укажите параметры нового образа", + "Create user":"Укажите данные для нового пользователя", + "Create Virtual Machine":"Укажите параметры виртуальной машины", + "Create Virtual Network":"Укажите параметры виртуальной сети", + "Create VM Template":"Укажите параметры шаблона ВМ", + "Current disks":"Используемые диски", + "Current inputs":"Используемые устройства ввода", + "Current leases":"Адреса виртуальной сети", + "Current NICs":"Используемые контроллеры сетевого интерфейса", + "Current variables":"Используемые переменные", + "Custom attribute name and value must be filled in":"Поля названия и значения пользовательского атрибута обязательны к заполнению", + "Custom attributes":"Пользовательские атрибуты", + "Custom variable name and value must be filled in":"Поля «Имя переменной» и «Значение» должны быть заполнены", + "Custom variables":"Пользовательские переменные", + "Dashboard":"Инф. панель", + "Data":"Данные", + "Datablock":"Блок данных", + "Default":"По умолчанию", + "Default (current image type)":"По умолчанию (текущий тип образа)", + "Default (dummy)":"По умолчанию (заглушка)", + "Define a subnet by IP range":"Указать диапазон адресов", + "Delete":"Удалить", + "Delete host":"Удалить узел", + "Deploy":"Разместить на узле", + "Deploy ID":"№ размещения", + "Deploy # VMs":"Кол-во ВМ", + "Description":"Описание", + "Device prefix":"Префикс устройства", + "Device to be mounted as root":"Устройство, монтируемое как корневое", + "Device to map image disk. If set, it will overwrite the default device mapping":"Соответствие обозначения устройства образу диска. Опционально.", + "Disable":"Отключить", + "disabled":"откл", + "Disallow access to the VM through the specified ports in the TCP protocol":"Запретить доступ к ВМ через указанные порты для TCP протокола", + "Disallow access to the VM through the specified ports in the UDP protocol":"Запретить доступ к ВМ через указанные порты для UDP протокола", + "Disk":"Диск", + "Disk file location path or URL":"Маршрутное имя файла диска или URL", + "disk id":"№ диска", + "Disks":"Диски", + "Disk type":"Тип диска", + "Documentation":"Online-документация", + "Do you want to proceed?":"Хотите продолжить?", + "Driver":"Драйвер", + "Driver default":"Драйвер по умолчанию", + "Drivers":"Драйверы", + "Drop":"Сбросить", + "Dummy":"Заглушка", + "EC2":"EC2", + "Enable":"Включить", + "English":"English (EN)", + "Error":"Ошибка", + "failed":"дефектных", + "fd":"fd", + "Features":"Особенности", + "Fields marked with":"Поля, отмеченные символом ", + "File":"Файл", + "Filesystem type":"Тип файловой системы", + "Filesystem type for the fs images":"Тип файловой системы для образов ФС", + "Fill in a new password":"Введите новый пароль", + "Fixed network":"Фиксированные адреса", + "Floppy":"Floppy", + "Fold / Unfold all sections":"Свернуть/развернуть все разделы", + "Format":"Формат", + "FS":"FS", + "FS type":"Тип ФС", + "Graphics":"Средства графического доступа", + "Graphics type":"Обеспечить доступ через", + "Group":"Группа", + "Group ":"гр. ", + "Group name":"Название группы", + "Group permissions":"Права для группы", + "Groups":"Группы", + "Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.":"Аппаратное устройствое, которое будет отвечать за эмуляцию сетевого интерфейса. Для Xen это атрибут «vif».", + "hd":"hd", + "Historical monitoring information":"Мониторинг состояния", + "hold":"запретить", + "Hold":"Запретить размещение", + "Hold lease":"Запретить выдачу адреса", + "Host":"Узел", + "Host information":"Состояние узла", + "Hostname":"Название узла", + "Host name missing!":"Не указано название узла", + "Host parameters":"Параметры узла", + "Hosts":"Узлы", + "Hosts CPU":"Загрузка ЦП", + "Host shares":"Ресурсы узла", + "Hosts memory":"Загрузка ОЗУ", + "Hosts (total/active)":"Узлы (всего/из них активных)", + "Host template":"Шаблон узла", + "Human readable description of the image for other users.":"Краткое описание образа.", + "HW address associated with the network interface":"MAC-адрес, связанный с сетевым интерфейсом", + "Icmp":"ICMP", + "ICMP policy":"Политика ICMP", + "id":"№", + "ID":"№", + "IDE":"IDE", + "Image":"Образ", + "Image cannot be public and persistent":"Образ не может быть открытым и постоянным одновременно", + "Image information":"Информация об образе", + "Image name":"Название образа", + "Images":"Образы ВМ", + "Images (total/public)":"Образы (всего/из них открытых)", + "Image template":"Шаблон образа", + "IM MAD":"Модуль средства мониторинга", + "Info":"Информация", + "information":" ", + "Information":"Информация", + "Information Manager":"Средство мониторинга", + "Initrd":"initrd", + "Inputs":"Устройства ввода", + "Instantiate":"Создать экземпляр ВМ", + "IP":"IP-адрес", + "IP End":"до", + "IP Start":"от", + "IP to listen on":"IP-адрес для прослушивания", + "Kernel":"Ядро", + "Kernel commands":"Команды ядра", + "Keyboard configuration locale to use in the VNC display":"Раскладка клавиатуры, используемая при работе с VNC-дисплеем", + "Keymap":"Раскладка клавиатуры", + "KVM":"KVM", + "Language":"Язык интерфейса", + "LCM State":"Текущее состояние ВМ", + "Lease IP":"IP адрес", + "Lease MAC (opt):":"MAC адрес (необ.):", + "Lease management":"Управление адресами виртуальной сети", + "Leases information":"Сведения по имеющимся адресам виртуальной сети", + "Listen IP":"Прослушивание IP-адреса", + "Live migrate":"Перенести запущенную ВМ", + "Loading":"Идет загрузка", + "MAC":"MAC-адрес", + "Make non persistent":"Сделать непостоянным", + "Make persistent":"Сделать постоянным", + "Manage":"Управление", + "Manual":"Вручную", + "Max Mem":"Доступно ОЗУ", + "Memory":"Память", + "Memory monitoring information":"Мониторинг ОЗУ", + "Memory use":"Использование ОЗУ", + "Migrate":"Перенести ВМ", + "Model":"Модель", + "Monitoring information":"Мониторинг", + "Mount image as read-only":"Монтировать образ только для чтения", + "Mouse":"Мышь", + "Name":"Название", + "Name for the context variable":"Имя контекстной переменной", + "Name for the custom variable":"Имя пользовательской переменной", + "Name for the tun device created for the VM":"Имя сетевого туннеля, созданного для ВМ", + "Name of a shell script to be executed after creating the tun device for the VM":"shell-скрипт, который будет выполнен после создания сетевого туннеля для ВМ", + "Name of the bridge the network device is going to be attached to":"Шлюз, с которым будет связано сетевое устройство", + "Name of the image to use":"Название образа для использования", + "Name of the network to attach this device":"Сеть, подключаемая к данному устройству", + "Name that the Image will get. Every image must have a unique name.":"Название, которое получит образ. Каждый образ должен обладать уникальным названием.", + "Name that the VM will get for description purposes. If NAME is not supplied a name generated by one will be in the form of one-<VID>.":"Название, которое получит ВМ. Если название не будет указано, то оно будет сгенерировано в формате one-<№ ВМ>.", + "Net_RX":"Принято", + "Net_TX":"Отправлено", + "network":"network", + "Network":"Сеть", + "Network Address":"Адрес сети", + "Network is unreachable: is OpenNebula running?":"Сеть недоступна. Проверьте, запущена ли OpenNebula.", + "Network mask":"Маска подсети", + "Network Mask":"Маска подсети", + "Network reception":"Сеть: принято", + "Network transmission":"Сеть: отправлено", + "Network type":"Тип сети", + "New":"Создать новый ресурс", + "+ New":"Создать", + "+ New Group":"Создать группу", + "New password":"Новый пароль", + "No":"Нет", + "No disk id or image name specified":"Внимание! Следует указать № диска или имя образа.", + "No disks defined":"Дисков не обнаружено", + "No leases to show":"Список пуст", + "None":"Никакой", + "Number of virtual cpus. This value is optional, the default hypervisor behavior is used, usually one virtual CPU.":"Количество виртуальных процессоров. Это значение опционально, используется поведение гипервизора по умолчанию - один виртуальный ЦП.", + "OK":"OK", + "Open VNC Session":"Открыть VNC-сессию", + "Optional, please select":"Опционально, пожалуйста выберите", + "OS":"ОС", + "OS and Boot options":"Опции загрузки и ОС", + "Other":"Все остальные", + "Other permissions":"Права для всех остальных", + "Owned by group":"Принадлежит группе", + "Owner":"Владелец", + "Owner permissions":"Права владельца", + "PAE":"PAE", + "Password":"Пароль", + "Password for the VNC server":"Пароль для VNC сервера", + "Path":"Путь к файлу", + "Path to the bootloader executable":"Путь к исполняемому файлу загрузчика", + "Path to the initrd image":"Путь к образу initrd", + "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.":"Путь к исходному файлу, который будет скопирован в хранилище образов. Если путь не указан для типа образа БЛОК ДАННЫХ, то будет создан пустой образ.", + "Path to the OS kernel to boot the image":"Путь к ядру ОС для загрузки образа", + "Path vs. source":"Путь к файлу образа или источник", + "Percentage of CPU divided by 100 required for the Virtual Machine. Half a processor is written 0.5.":"Процент процессорного времени ЦП, предоставляемого ВМ, разделенный на 100. Например, для выделения половины процессорного времени следует указать 0.5.", + "Permissions":"Права", + "Permits access to the VM only through the specified ports in the TCP protocol":"Разрешить доступ к ВМ только через указанные порты протокола TCP", + "Permits access to the VM only through the specified ports in the UDP protocol":"Разрешить доступ к ВМ только через указанные порты протокола UPD", + "Persistence of the image":"Если образ является постоянным, то при каждом завершении работы с полученной на его основе виртуальной машиной все изменения будут сохранены в образе. Важно помнить, что сохранение выполнится только в случае завершения работы соответствующей ВМ при помощи операций «Выключить» и «Отменить». Постоянный образ всегда хранится в одном экземпляре.", + "Persistent":"Постоянный", + "Physical address extension mode allows 32-bit guests to address more than 4 GB of memory":"Режим расширенной физической адресации позволяет использовать 32-битным ВМ больше 4-х ГБ ", + "Physical device":"Устройство", + "Placement":"Размещение", + "Please choose":"Пожалуйста выберите", + "Please, choose and modify the image you want to update":"Выберите образ и внесите необходимые изменения в его параметры", + "Please, choose and modify the template you want to update":"Выберите шаблон ВМ и внесите необходимые изменения в его параметры", + "Please, choose and modify the virtual machine you want to update":"Выберите ВМ и внесите необходимые изменения в его параметры", + "Please, choose and modify the virtual network you want to update":"Выберите виртуальную сеть и внесите необходимые изменения в ее параметры", + "Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.":"«Путь к эталонному файлу образа» — образ создается путем копирования эталонного файла образа в хранилище образов. «Источник» — в данное поле следует указывать местоположение образа (в качестве образа будет использован ресурс, непосредственно указанный в поле «Источник», а не копия этого ресурса).", + "Please choose the new type of authentication for the selected users":"Укажите новый способ аутентификации для выбранных пользователей", + "Please provide a lease IP":"Необходимо указать IP-адрес", + "Please provide a network address":"Укажите адрес сети", + "Please provide a resource ID for the resource(s) in this rule":"Необходимо указать № ресурса(ов) для данного правила)", + "Please select":"выберите", + "Please select at least one resource":"Необходимо выбрать по меньшей мере один ресурс", + "Please specify to who this ACL applies":"Необходимо указать, к кому применять данный список контроля", + "Port":"Порт", + "Port blacklist":"Список запрещенных портов", + "Port for the VNC server":"Порт для сервера VNC", + "Port whitelist":"Список разрешенных портов", + "Predefined":"По умолчанию", + "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”).":"Префикс эмулируемого устройства, на которое будет смонтирован образ. Например, «hd» и «sd». Если не указать префикс, его значение будет считано из конфигурационного файла oned.conf (значение по умолчанию — «hd»).", + "Previous action":"Предыдущее действие", + "Provide a path":"Указать путь к эталонному файлу образа", + "Provide a source":"Указать источник для образа", + "PS2":"PS/2", + "Public":"Public", + "Public scope of the image":"Область видимости образа", + "Publish":"Сделать открытым", + "Quickstart":"Типовые операции", + "Ranged network":"Диапазон адресов", + "Rank":"Степень", + "Raw":"Исходная опция", + "Raw data to be passed directly to the hypervisor":"Исходные данные, передаваемые напрямую гипервизору", + "Read only":"только на чтение", + "Reboot":"Перезагрузить", + "Refresh list":"Обновить список", + "Register time":"Время регистрации", + "Registration time":"Время регистрации", + "release":"размещение", + "Release":"Разрешить размещение", + "Remove selected":"Удалить", + "Request an specific IP from the Network":"Запросить определенный IP-адрес из сети", + "Requirements":"Требования", + "Reset":"«Сбросить» все поля", + "Resource ID":"№ ресурса", + "Resource ID / Owned by":"№ ресурса / Принадлежит", + "Resource subset":"Подмножество ресурсов", + "Restart":"Перезапустить", + "Resubmit":"Разместить повторно", + "Resume":"Возобновить работу ВМ", + "Retrieving":"Запрос сведений", + "Root":"Корень", + "running":"запущенных", + "Running VMs":"Запущено ВМ", + "Running #VMS":"Кол-во запущенных ВМ", + "Russian":"Русский (RU)", + "Save":"Сохранить", + "Save as":"Сохранить как", + "Saveas for VM with ID":"Сохранить как для ВМ с №", + "Save this image after shutting down the VM":"Сохранить образ после выключения ВМ", + "Script":"Скрипт", + "SCSI":"SCSI", + "SDL":"SDL", + "Select a network":"Выберите виртуальную сеть", + "Select an image":"Выберите образ", + "Select a template":"Выберите шаблон", + "Select a VM":"Выберите вирт. машину", + "Select boot method":"Выберите метод загрузки", + "Select disk":"Выберите диск", + "Select template":"Шаблон", + "Select the new group":"Выберите новую группу", + "Select the new owner":"Выберите нового владельца", + "Server (Cipher)":"Server (Cipher)", + "Server (x509)":"Server (x509)", + "Setup Networks":"Настройка сетей", + "Shared":"Общий каталог", + "Shutdown":"Выключить", + "Sign out":"Выйти из сервиса", + "Size":"Размер", + "Size in MB":"Размер в МБ", + "Size (Mb)":"Размер (МБ)", + "Size of the datablock in MB.":"Размер блока данных в МБ.", + "Skipping VM ":"Пропуск ВМ ", + "Source":"Источник", + "Source to be used in the DISK attribute. Useful for not file-based images.":"В качестве источника указывается местоположение образа, который планируется использовать непосредственно.", + "Specific ID":"Ресурс с конкретным №", + "Specific image mapping driver. KVM: raw, qcow2. XEN: tap:aio, file:":"Формат образа виртуального диска. Для KVM: raw, qcow2. Для Xen: tap:aio, file:", + "Specific image mapping driver. KVM: raw, qcow2. Xen:tap:aio:, file:. VMware unsupported":"Формат образа виртуального диска. Для KVM: raw, qcow2. Для Xen: tap:aio:, file:. Форматы VMware не поддерживаются", + "SSH":"SSH", + "Start time":"Время запуска", + "Start Time":"Время запуска", + "State":"Состояние", + "Status":"Статус", + "Stop":"Остановить", + "Submitted":"Выполнено", + "Summary of resources":"Использование ресурсов", + "Sunstone UI Configuration":"Конфигурация интерфейса Sunstone", + "Support":"Сведения о поддержке", + "Suspend":"Приостановить работу ВМ", + "Swap":"Swap", + "Tablet":"Планшетный ПК", + "Target":"Цель", + "Tcp black ports":"Запрещенные TCP-порты", + "Tcp firewall mode":"Режим брандмауэра TCP", + "Tcp white ports":"Разрешенные TCP-порты", + "Template":"Шаблон", + "Template information":"Сведения о шаблоне", + "Templates":"Шаблоны ВМ", + "Template updated correctly":"Шаблон успешно обновлен", + "There are mandatory fields missing in the capacity section":"В разделе «Производительность» не заполнены некоторые обязательные поля", + "There are mandatory fields missing in the OS Boot options section":"В разделе «Загрузка и тип ОС» не заполнены некоторые обязательные поля", + "There are mandatory parameters missing":"Указаны не все обязательные параметры.", + "There are mandatory parameters missing in this section":"В данном разделе указаны не все обязательные параметры", + "There is no more monitoring information for host":"Отсутствуют данные по мониторингу для узла", + "This field sets which attribute will be used to sort the suitable hosts for this VM. Basically, it defines which hosts are more suitable than others":"В данном поле устанавливается значение атрибута, используемое для ранжирования узлов, пригодных для размещения ВМ. Значение атрибута определяет, какие из узлов лучше подходят для размещения ВМ.", + "This rule applies to":"Область применения", + "This will cancel selected VMs":"Прервать работу выбранных ВМ", + "This will change the main group of the selected users. Select the new group":"Выберите основную группу для выбранных пользователей", + "This will change the password for the selected users":"Введите новый пароль для выбранных пользователей", + "This will delete the selected VMs from the database":"Удалить выбранные ВМ и связанные с ними образы дисков из базы данных и хранилища образов", + "This will deploy the selected VMs on the chosen host":"Разместить выбранные ВМ на определенном узле", + "This will hold selected pending VMs from being deployed":"Приостановить процедуру размещения ВМ на узле", + "This will initiate the shutdown process in the selected VMs":"Данное действие запустит процесс выключения выбранных ВМ.", + "This will live-migrate the selected VMs to the chosen host":"Перенести выбранные запущенные ВМ, не завершая их работы, с текущих узлов на выбранный", + "This will migrate the selected VMs to the chosen host":"Перенести выбранные остановленные ВМ с текущих узлов на выбранный", + "This will redeploy selected VMs (in UNKNOWN or BOOT state)":"Повторно выполнить процедуру размещения выбранных ВМ, находящихся в состоянии UNKNOWN или BOOT, на узле", + "This will release held machines":"Продолжить ранее приостановленное размещение ВМ на узле", + "This will resubmits VMs to PENDING state":"Повторно выполнить попытку размещения выбранных ВМ на одном из доступных узлов системы виртуализации (перевод в состояние PENDING)", + "This will resume selected stopped or suspended VMs":"Возобновить работу выбранных остановленных или приостановленных ВМ", + "This will send a reboot action to running VMs":"Отправить запущенным виртуальным машинам команду на перезагрузку", + "This will suspend selected machines":"Приостановить выбранные ВМ", + "TM MAD":"Модуль средства передачи", + "total":"всего", + "Total Leases":"Суммарное количество адресов", + "Total VM count":"Количество виртуальных машин", + "Total VM CPU":"Всего ЦП для ВМ", + "Total VM Memory":"Всего ОЗУ для ВМ", + "Transfer Manager":"Средство передачи", + "Type":"Тип", + "Type of disk device to emulate.":"Тип эмулируемого дискового устройства", + "Type of disk device to emulate: ide, scsi":"Тип эмулируемого дискового устройства: ide, scsi", + "Type of file system to be built. This can be any value understood by mkfs unix command.":"Тип создаваемой ФС. Может быть указан любой тип, который используется в unix-команде mkfs.", + "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).":"Тип. Если не указать тип образа, его значение будет считано из конфигурационного файла oned.conf (значение по умолчанию — «OS»).", + "Udp black ports":"Запрещенные UDP-порты", + "Udp firewall mode":"Режим брандмауэра UDP", + "Udp white ports":"Разрешенные UDP-порты", + "Unauthorized":"Неавторизован", + "Unpublish":"Отменить статус «Открытый»", + "Update":"Сохранить изменения", + "Update a template":"Редактировать шаблон", + "Update image properties":"Редактировать свойства образа", + "Update image template":"Обновить шаблон образа", + "Update network properties":"Обновить свойства виртуальной сети", + "Update network template":"Обновить шаблон виртуальной сети", + "Update properties":"Редактировать свойства", + "Update template":"Редактировать шаблон", + "Update template properties":"Свойства шаблона", + "Update VM properties":"Свойства ВМ", + "USB":"USB", + "Use":"Пользование", + "Used by VM":"Используется ВМ", + "Used CPU":"Используется ЦП", + "Used CPU (allocated)":"Использовано ОЗУ (реально)", + "Used CPU (real)":"Использовано ЦП (реально)", + "Used Mem (allocated)":"Использовано ОЗУ (выделено)", + "Used Memory":"Используется памяти", + "Used Mem (real)":"Использовано ОЗУ (реально)", + "Useful for power management, for example, normally required for graceful shutdown to work":"Требуется для корректного завершения работы ВМ средствами системы виртуализации", + "User":"Пользователь", + "Username":"Имя пользователя", + "User name and password must be filled in":"Необходимо указать и имя пользователя, и пароль", + "Users":"Пользователи", + "Value":"Значение", + "Value of the context variable":"Значение контекстной переменной", + "Value of the custom variable":"Значение пользовательской перменной", + "VCPU":"Кол-во вирт. ЦП", + "Virtio":"Virtio", + "Virtio (KVM)":"Virtio (KVM)", + "Virtualization Manager":"Средство виртуализации", + "Virtual Machine information":"Информация о виртуальной машине", + "Virtual Machines":"Вирт. машины", + "Virtual Network":"Виртуальная сеть", + "Virtual network information":"Информация о виртуальной сети", + "Virtual Network information":"Информация о виртуальной сети", + "Virtual Network Manager":"Средство управления вирт. сетью", + "Virtual Network name missing!":"Отсутствует название виртуальной сети!", + "Virtual Networks":"Вирт. сети", + "Virtual Networks (total/public)":"Виртуальные сети (всего/из них открытых)", + "Virtual Network template (attributes)":"Шаблон виртуальной сети (атрибуты)", + "VM information":"Информация о ВМ", + "VM Instance":"Экземпляр ВМ", + "VM Instances":"Экземпляры ВМ", + "VM log":"Журнал ВМ", + "VM MAD":"Модуль средства виртуализации", + "VM Name":"Название ВМ", + "VM Network stats":"Статистика виртуальных сетей", + "#VMS":"Кол-во ВМ", + "VM Save As":"ВМ сохранить как", + "VM template":"Шаблон ВМ", + "VM Template":"Шаблон ВМ", + "VM Templates":"Шаблоны ВМ", + "VM Templates (total/public)":"Шаблоны ВМ (всего/из них открытых)", + "VNC":"VNC", + "VNC Access":"Доступ по VNC", + "VNC connection":"VNC соединение", + "VNC Disabled":"VNC недоступно", + "VNC Session":"VNC сессия", + "VNET ID":"VNET ID", + "VN MAD":"Модуль средства управления вирт. сетью", + "Welcome":"Текущий пользователь:", + "Wizard":"Мастер настройки", + "Wizard KVM":"Шаблон KVM", + "Wizard VMware":"Шаблон VMware", + "Wizard XEN":"Шаблон XEN", + "Write the image template here":"Отредактируйте параметры шаблона образа ВМ вручную", + "Write the Virtual Machine template here":"Отредактируйте параметры шаблона ВМ вручную", + "Write the Virtual Network template here":"Отредактируйте параметры шаблона вирт. сети вручную", + "x509":"x509", + "XEN":"XEN", + "Xen templates must specify a boot method":"В шаблон Xen необходимо указывать метод загрузки", + "yes":"да", + "Yes":"Да", + "You have not selected a template":"Вы не выбрали шаблон", + "You have to confirm this action.":"Необходимо подтвердить данную операцию.", + "You need to select something.":"Вы должны что-нибудь выбрать.", + + // ********************************* + "active":"активных", + "cpu_usage":"использование", + "error":"ошибки", + "Loading new language... please wait":"Выполняется загрузка языковых файлов...", + "max_cpu":"максимально", + "max_mem":"максимально", + "mem_usage":"использование", + "net_rx":"принято", + "net_tx":"отправлено", + "no":"нет", + "used_cpu":"использовано", + "used_mem":"использовано", }; From b40cd695d2e6b6d4235e17cd53f5681786208976 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 13:31:45 +0100 Subject: [PATCH 17/64] Sunstone: require confirmation when deleting --- src/sunstone/public/js/plugins/acls-tab.js | 2 +- src/sunstone/public/js/plugins/groups-tab.js | 2 +- src/sunstone/public/js/plugins/hosts-tab.js | 2 +- src/sunstone/public/js/plugins/images-tab.js | 2 +- src/sunstone/public/js/plugins/templates-tab.js | 2 +- src/sunstone/public/js/plugins/users-tab.js | 2 +- src/sunstone/public/js/plugins/vnets-tab.js | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index 06785b134d..dc962d3b1b 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -146,7 +146,7 @@ var acl_buttons = { text: tr("+ New") }, "Acl.delete" : { - type: "action", + type: "confirm", text: tr("Delete") } } diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 1a31960052..6c193740c3 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -134,7 +134,7 @@ var group_buttons = { // }, "Group.delete" : { - type: "action", + type: "confirm", text: tr("Delete") } }; diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 48c6802dcf..01ad24d35e 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -273,7 +273,7 @@ var host_buttons = { text: tr("Disable") }, "Host.delete" : { - type: "action", + type: "confirm", text: tr("Delete host") } }; diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index b2a0aee838..65b0d74850 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -456,7 +456,7 @@ var image_buttons = { } }, "Image.delete" : { - type: "action", + type: "confirm", text: tr("Delete") } } diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 8252f55f2e..50af554a14 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -815,7 +815,7 @@ var template_buttons = { } }, "Template.delete" : { - type: "action", + type: "confirm", text: tr("Delete") } } diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index e702a0d0b4..64524e56fd 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -282,7 +282,7 @@ var user_buttons = { // condition: True // }, "User.delete" : { - type: "action", + type: "confirm", text: tr("Delete") } } diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index ea4a7fb2c8..43dbea9a90 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -401,7 +401,7 @@ var vnet_buttons = { }, "Network.delete" : { - type: "action", + type: "confirm", text: tr("Delete") } } From 36d05b4365cff3c2555ff76ba6784583654c6e90 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 16:31:14 +0100 Subject: [PATCH 18/64] SelfService: Improve file upload so it doesn't eat up RAM. --- src/cloud/occi/lib/occi-server.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index 3c184f73be..1d6829a924 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -50,6 +50,7 @@ require 'sinatra' require 'yaml' require 'erb' require 'tempfile' +require 'fileutils' require 'json' require 'OCCIServer' @@ -353,9 +354,8 @@ end post '/ui/upload' do file = Tempfile.new('uploaded_image') + FileUtils.cp(request.env['rack.input'].path,file.path) request.params['file'] = file.path #so we can re-use occi post_storage() - file.write(request.env['rack.input'].read) - #file.close # this would allow that file is garbage-collected result,rc = @occi_server.post_storage(request) treat_response(result,rc) end From 33763c38c938e5af60455f2995470ca9d7fa53a3 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 16:31:58 +0100 Subject: [PATCH 19/64] Restore refresh time inverval --- src/sunstone/public/js/sunstone-util.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 1f1abed1f6..17ae492304 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -16,7 +16,7 @@ /* Some useful functions for Sunstone default plugins */ -var INTERVAL=300000; //milisecs +var INTERVAL=60000; //milisecs function someTime(){ return Math.floor(Math.random()*30000); From 60b8e15ee9a28eabcdfaf00d4cb23d34e4a7a339 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 16:39:28 +0100 Subject: [PATCH 20/64] SelfSerice: Do not open info panels on empty list click. --- src/cloud/occi/lib/ui/public/js/plugins/compute.js | 5 ++++- src/cloud/occi/lib/ui/public/js/plugins/network.js | 7 +++++-- src/cloud/occi/lib/ui/public/js/plugins/storage.js | 4 +++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index 09ee6c434e..57d459e8ed 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -427,9 +427,12 @@ function vMachineInfoListener(){ $('#tbodyvmachines tr',dataTable_vMachines).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(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("VM.showinfo",id); return false; }); diff --git a/src/cloud/occi/lib/ui/public/js/plugins/network.js b/src/cloud/occi/lib/ui/public/js/plugins/network.js index d66d45d1f8..bea0712a18 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/network.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/network.js @@ -237,10 +237,13 @@ function vNetworkElementArray(vn_json){ function vNetworkInfoListener(){ $('#tbodyvnetworks tr',dataTable_vNetworks).live("click", function(e){ - if ($(e.target).is('input')) {return true;} - popDialogLoading(); + if ($(e.target).is('input')) {return true;}; + var aData = dataTable_vNetworks.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Network.showinfo",id); return false; }); diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index 7a4b3be704..28221a7164 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -308,9 +308,11 @@ function imageInfoListener(){ if (target.is('input') || target.is('select') || target.is('option')) return true; - popDialogLoading(); var aData = dataTable_images.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Image.showinfo",id); return false; }); From 0b0d0d1166d1e7398ec9c19222c1c6a6781a8d91 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 16:43:56 +0100 Subject: [PATCH 21/64] Sunstone: do not open info tabs when clicking on empty tables --- src/sunstone/public/js/plugins/hosts-tab.js | 5 ++++- src/sunstone/public/js/plugins/images-tab.js | 4 +++- src/sunstone/public/js/plugins/templates-tab.js | 5 ++++- src/sunstone/public/js/plugins/vms-tab.js | 5 ++++- src/sunstone/public/js/plugins/vnets-tab.js | 5 ++++- 5 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 01ad24d35e..df6812f1c2 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -369,9 +369,12 @@ function hostInfoListener(){ $('#tbodyhosts tr',dataTable_hosts).live("click",function(e){ //do nothing if we are clicking a checkbox! if ($(e.target).is('input')) {return true;} - popDialogLoading(); + var aData = dataTable_hosts.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Host.showinfo",id); return false; }); diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 65b0d74850..a6d3b399d3 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -528,9 +528,11 @@ function imageInfoListener(){ if (target.is('input') || target.is('select') || target.is('option')) return true; - popDialogLoading(); var aData = dataTable_images.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Image.showinfo",id); return false; }); diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 50af554a14..750c427ad8 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -865,9 +865,12 @@ function templateElementArray(template_json){ function templateInfoListener(){ $('#tbodytemplates tr',dataTable_templates).live("click",function(e){ if ($(e.target).is('input')) {return true;} - popDialogLoading(); + var aData = dataTable_templates.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Template.showinfo",id); return false; }); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 711ef48fd4..235800ecd7 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -651,9 +651,12 @@ function vMachineInfoListener(){ $('#tbodyvmachines tr',dataTable_vMachines).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(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("VM.showinfo",id); return false; }); diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 43dbea9a90..4f9ce9e6fe 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -457,9 +457,12 @@ function vNetworkInfoListener(){ $('#tbodyvnetworks tr',dataTable_vNetworks).live("click", function(e){ if ($(e.target).is('input')) {return true;} - popDialogLoading(); + var aData = dataTable_vNetworks.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Network.showinfo",id); return false; }); From 7010b29b8f3ce73c791d5a6965fca70f5aed0ce9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 16:45:56 +0100 Subject: [PATCH 22/64] oZones: do not open info tab when clicking on empty tables --- src/ozones/Server/public/js/plugins/vdcs-tab.js | 7 +++++-- src/ozones/Server/public/js/plugins/zones-tab.js | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index d46b8edacd..cb0e0a718d 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -234,11 +234,14 @@ function vdcElementArray(vdc_json){ } function vdcInfoListener() { - $("#tbodyvdcs tr").live("click", function(e){ + $("#tbodyvdcs tr").live("click", function(e){ if ($(e.target).is('input')) {return true;} - popDialogLoading(); + var aData = dataTable_vdcs.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("VDC.showinfo",id); return false; }); diff --git a/src/ozones/Server/public/js/plugins/zones-tab.js b/src/ozones/Server/public/js/plugins/zones-tab.js index 2bce15b604..2f5e305264 100644 --- a/src/ozones/Server/public/js/plugins/zones-tab.js +++ b/src/ozones/Server/public/js/plugins/zones-tab.js @@ -244,9 +244,12 @@ function zoneElementArray(zone_json){ function zoneInfoListener(){ $("#tbodyzones tr").live("click", function(e){ if ($(e.target).is('input')) {return true;} - popDialogLoading(); + var aData = dataTable_zones.fnGetData(this); var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); Sunstone.runAction("Zone.showinfo",id); return false; }); From 8182fa492943bef043c5c2f8295371f80e3cf0a0 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 12 Jan 2012 18:26:35 +0100 Subject: [PATCH 23/64] Ozones: add locale.js, otherwise sunstone.js sunstone-util.js scripts fail --- src/ozones/Server/templates/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ozones/Server/templates/index.html b/src/ozones/Server/templates/index.html index 09b1677e83..f842269c02 100644 --- a/src/ozones/Server/templates/index.html +++ b/src/ozones/Server/templates/index.html @@ -20,6 +20,7 @@ + From 8b7945d0fb6ec3818fc3ae4893f66528ed486bc6 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 13 Jan 2012 13:03:48 +0100 Subject: [PATCH 24/64] Small fixes in UIs Left Menu
  • items are clickable instead of . Corrected some typos. Updated language template. --- src/cloud/occi/lib/ui/public/js/layout.js | 8 ++++---- src/sunstone/public/js/layout.js | 8 ++++---- src/sunstone/public/js/plugins/templates-tab.js | 2 +- src/sunstone/public/js/plugins/users-tab.js | 2 +- src/sunstone/public/locale/en_US/en_US.js | 3 --- 5 files changed, 10 insertions(+), 13 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/layout.js b/src/cloud/occi/lib/ui/public/js/layout.js index 71b0098548..a7dd7386fd 100644 --- a/src/cloud/occi/lib/ui/public/js/layout.js +++ b/src/cloud/occi/lib/ui/public/js/layout.js @@ -57,14 +57,14 @@ function showTab(tabname){ $(document).ready(function () { $(".tab").hide(); - $(".outer-west ul li.subTab a").live("click",function(){ - var tab = $(this).attr('href'); + $(".outer-west ul li.subTab").live("click",function(){ + var tab = $('a',this).attr('href'); showTab(tab); return false; }); - $(".outer-west ul li.topTab a").live("click",function(){ - var tab = $(this).attr('href'); + $(".outer-west ul li.topTab").live("click",function(){ + var tab = $('a',this).attr('href'); //toggle subtabs trick $('li.'+tab.substr(1)).toggle(); showTab(tab); diff --git a/src/sunstone/public/js/layout.js b/src/sunstone/public/js/layout.js index ab4f193001..da068aadb0 100644 --- a/src/sunstone/public/js/layout.js +++ b/src/sunstone/public/js/layout.js @@ -57,14 +57,14 @@ function showTab(tabname){ $(document).ready(function () { $(".tab").hide(); - $(".outer-west ul li.subTab a").live("click",function(){ - var tab = $(this).attr('href'); + $(".outer-west ul li.subTab").live("click",function(){ + var tab = $('a',this).attr('href'); showTab(tab); return false; }); - $(".outer-west ul li.topTab a").live("click",function(){ - var tab = $(this).attr('href'); + $(".outer-west ul li.topTab").live("click",function(){ + var tab = $('a',this).attr('href'); //toggle subtabs trick $('li.'+tab.substr(1)).toggle(); showTab(tab); diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 750c427ad8..4b846d31ed 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -587,7 +587,7 @@ var update_template_tmpl = '
    \

    '+tr("Please, choose and modify the template you want to update")+':

    \
    \ - \ + \ \
    \
    \ diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 64524e56fd..bd0c655020 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -241,7 +241,7 @@ var user_buttons = { }, "User.update_dialog" : { type: "action", - text: tr("Update a template"), + text: tr("Update properties"), alwaysActive: true }, "User.update_password" : { diff --git a/src/sunstone/public/locale/en_US/en_US.js b/src/sunstone/public/locale/en_US/en_US.js index 11bce91eb5..abd23e3ef1 100644 --- a/src/sunstone/public/locale/en_US/en_US.js +++ b/src/sunstone/public/locale/en_US/en_US.js @@ -139,7 +139,6 @@ locale={ "Group":"", "Group ":"", "Group name":"", - "Group permissions":"", "Groups":"", "Hardware that will emulate this network interface. With Xen this is the type attribute of the vif.":"", "hd":"", @@ -249,10 +248,8 @@ locale={ "OS":"", "OS and Boot options":"", "Other":"", - "Other permissions":"", "Owned by group":"", "Owner":"", - "Owner permissions":"", "PAE":"", "Password":"", "Password for the VNC server":"", From 7b50ba8e4a4135e5402295742e7347d7c894dad9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 13 Jan 2012 13:16:34 +0100 Subject: [PATCH 25/64] Ozones: preload selected zone hosts when opening create vdc dialog --- src/ozones/Server/public/js/plugins/vdcs-tab.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index cb0e0a718d..190054ba90 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -517,6 +517,7 @@ function setupCreateVDCDialog(){ function openCreateVDCDialog(){ var dialog = $('div#create_vdc_dialog') $('select#zoneid',dialog).html(zones_select); + $('select#zoneid',dialog).trigger("change"); $('#vdc_available_hosts_list',dialog).empty(); $('#vdc_selected_hosts_list',dialog).empty(); dialog.dialog('open'); From 0bee9b76f6b835f23bf8d5cf6f307464970e7e46 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 13 Jan 2012 15:16:58 +0100 Subject: [PATCH 26/64] Ozones: Add "/" to the end of sunstone public link --- src/ozones/Server/public/js/plugins/vdcs-tab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index 190054ba90..a1542e5edf 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -287,7 +287,7 @@ function updateVDCInfo(req,vdc_json){ if (zone_match){ zone_host = zone_match[1]; zone_port = zone_match[2]; - sun_link = "http://" + zone_host +"/sunstone_"+ vdc.NAME; + sun_link = "http://" + zone_host +"/sunstone_"+ vdc.NAME+"/"; }; var info_tab = { From 8d18227865885970ffc305a442b46f1eab14f3b9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 13 Jan 2012 20:00:13 +0100 Subject: [PATCH 27/64] SelfService: small fixes Add checkboxes to compute creation resource selects. Add ids next to the checkboxes names. Hitting return now submits instead of closing the creation dialogs. Treat the case when description is undefined. --- .../occi/lib/ui/public/js/plugins/compute.js | 16 ++++++++++++---- .../occi/lib/ui/public/js/plugins/network.js | 4 ++-- .../occi/lib/ui/public/js/plugins/storage.js | 6 +++--- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index fb64497c31..aaab2fc1c4 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -93,8 +93,8 @@ var create_vm_tmpl ='\ \
    \
    \ - \ - \ + \ + \ \
    \
  • \ @@ -695,6 +695,10 @@ function popUpCreateVMDialog(){ ); $('#network_box',dialog).html(net_select); + $('#network_box option',dialog).each(function(){ + $(this).text('☐ '+$(this).text()+' (id:'+$(this).val()+')'); + }); + var image_select = makeSelectOptions(dataTable_images, 1,//id_col @@ -704,6 +708,10 @@ function popUpCreateVMDialog(){ true); $('#disk_box',dialog).html(image_select); + $('#disk_box option',dialog).each(function(){ + $(this).text('☐ '+$(this).text()+' (id:'+$(this).val()+')'); + }); + $('#network_box,#disk_box',dialog).change(function(){ $(this).val(""); @@ -713,11 +721,11 @@ function popUpCreateVMDialog(){ $('#network_box option,#disk_box option',dialog).click(function(){ var clicked = $(this).attr('clicked'); if (clicked){//unbold, unmark - $(this).text($(this).text().replace(/✓/g,'')); + $(this).text($(this).text().replace(/☒/g,'☐')); $(this).removeAttr('clicked'); } else {//bold,mark - $(this).text("✓"+$(this).text()); + $(this).text($(this).text().replace(/☐/g,'☒')); $(this).attr('clicked','clicked'); } return false; diff --git a/src/cloud/occi/lib/ui/public/js/plugins/network.js b/src/cloud/occi/lib/ui/public/js/plugins/network.js index 436b040939..257eb9cf04 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/network.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/network.js @@ -53,8 +53,8 @@ var create_vn_tmpl =
    \ \
    \ - \ - \ + \ + \ \
    \ \ diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index d6fbfe10d9..5b7f768d40 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -92,8 +92,8 @@ var create_image_tmpl =
    \ -->\
    \ - \ - \ + \ + \ \
    \ \ @@ -369,7 +369,7 @@ function updateImageInfo(request,img){ \ \ '+tr("Description")+'\ - '+img_info.DESCRIPTION+'\ + '+(img_info.DESCRIPTION ? img_info.DESCRIPTION : "--")+'\ \ \ '+tr("Type")+'\ From a99477871abd11718555fef62118e19e9d2768ff Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Sat, 14 Jan 2012 14:43:11 +0100 Subject: [PATCH 28/64] Sunstone: add user info tab Information tab pops up when clicking on elements from the user table. --- src/sunstone/public/js/plugins/users-tab.js | 75 +++++++++++++++++++-- src/sunstone/public/locale/en_US/en_US.js | 2 + 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index bb5e20eda2..a9d35c164f 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -186,6 +186,13 @@ var user_actions = { error: onError }, + "User.showinfo" : { + type: "single", + call: OpenNebula.User.show, + callback: updateUserInfo, + error: onError + }, + "User.delete" : { type: "multiple", call: OpenNebula.User.delete, @@ -285,7 +292,14 @@ var user_buttons = { type: "confirm", text: tr("Delete") } -} +}; + +var user_info_panel = { + "user_info_tab" : { + title: tr("User information"), + content:"" + }, +}; var users_tab = { title: tr("Users"), @@ -295,6 +309,7 @@ var users_tab = { Sunstone.addActions(user_actions); Sunstone.addMainTab('users_tab',users_tab); +Sunstone.addInfoPanel("user_info_panel",user_info_panel); function userElements(){ return getSelectedNodes(dataTable_users); @@ -312,8 +327,21 @@ function userElementArray(user_json){ user.GNAME, user.AUTH_DRIVER ] -} +}; +function userInfoListener(){ + $('#tbodyusers tr',dataTable_users).live("click",function(e){ + //do nothing if we are clicking a checkbox! + if ($(e.target).is('input')) return true; + var aData = dataTable_users.fnGetData(this); + var id = $(aData[0]).val(); + if (!id) return true; + + popDialogLoading(); + Sunstone.runAction("User.showinfo",id); + return false; + }); +}; function updateUserSelect(){ users_select = makeSelectOptions(dataTable_users, @@ -354,7 +382,42 @@ function updateUsersView(request,users_list){ updateView(user_list_array,dataTable_users); updateDashboard("users",users_list); updateUserSelect(); -} +}; + +function updateUserInfo(request,user){ + var user_info = user.USER; + + var info_tab = { + title : tr("User information"), + content : + '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    ' + tr("User information") + ' - '+user_info.NAME+'
    ' + tr("id") + ''+user_info.ID+'
    ' + tr("Group") + ''+user_info.GNAME+'
    ' + tr("Authentication driver") + ''+user_info.AUTH_DRIVER+'
    \ + \ + '+ + prettyPrintJSON(user_info.TEMPLATE)+ + '
    ' + tr("User template") + '
    ' + }; + + Sunstone.updateInfoPanelTab("user_info_panel","user_info_tab",info_tab); + Sunstone.popUpInfoPanel("user_info_panel"); +}; // Prepare the user creation dialog function setupCreateUserDialog(){ @@ -461,7 +524,7 @@ $(document).ready(function(){ ], "oLanguage": (datatable_lang != "") ? { - sUrl: "locale/"+lang+"/"+datatable_lang + sUrl: "locale/"+lang+"/"+datatable_lang } : "" }); dataTable_users.fnClearTable(); @@ -478,5 +541,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_users); tableCheckboxesListener(dataTable_users); //shortenedInfoFields('#datatable_users'); - -}) + userInfoListener(); +}); diff --git a/src/sunstone/public/locale/en_US/en_US.js b/src/sunstone/public/locale/en_US/en_US.js index abd23e3ef1..91db79fee5 100644 --- a/src/sunstone/public/locale/en_US/en_US.js +++ b/src/sunstone/public/locale/en_US/en_US.js @@ -431,9 +431,11 @@ locale={ "Used Mem (real)":"", "Useful for power management, for example, normally required for graceful shutdown to work":"", "User":"", + "User information":"", "Username":"", "User name and password must be filled in":"", "Users":"", + "User template":"", "Value":"", "Value of the context variable":"", "Value of the custom variable":"", From 33dd4ac3139e9a250d14b13c94222df5fb7d045f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 16 Jan 2012 11:42:08 +0100 Subject: [PATCH 29/64] SelfService: remove usage of resource_str Helper. Disallow creation of VMs with empty name. --- src/cloud/occi/lib/ui/public/js/occi.js | 65 ------------------- .../occi/lib/ui/public/js/plugins/compute.js | 5 +- .../occi/lib/ui/public/js/plugins/storage.js | 2 +- 3 files changed, 4 insertions(+), 68 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/occi.js b/src/cloud/occi/lib/ui/public/js/occi.js index b5444a50c7..004938dc67 100644 --- a/src/cloud/occi/lib/ui/public/js/occi.js +++ b/src/cloud/occi/lib/ui/public/js/occi.js @@ -64,71 +64,6 @@ var OCCI = { }, "Helper": { - "resource_state": function(type, value) - { - switch(type) - { - case "HOST","host": - return ["INIT", - "MONITORING", - "MONITORED", - "ERROR", - "DISABLED"][value]; - break; - case "HOST_SIMPLE","host_simple": - return ["ON", - "ON", - "ON", - "ERROR", - "OFF"][value]; - break; - case "VM","vm": - return ["INIT", - "PENDING", - "HOLD", - "ACTIVE", - "STOPPED", - "SUSPENDED", - "DONE", - "FAILED"][value]; - break; - case "VM_LCM","vm_lcm": - return ["LCM_INIT", - "PROLOG", - "BOOT", - "RUNNING", - "MIGRATE", - "SAVE_STOP", - "SAVE_SUSPEND", - "SAVE_MIGRATE", - "PROLOG_MIGRATE", - "PROLOG_RESUME", - "EPILOG_STOP", - "EPILOG", - "SHUTDOWN", - "CANCEL", - "FAILURE", - "CLEANUP", - "UNKNOWN"][value]; - break; - case "IMAGE","image": - return ["INIT", - "READY", - "USED", - "DISABLED", - "LOCKED", - "ERROR"][value]; - break; - default: - return; - } - }, - - "image_type": function(value) - { - return ["OS", "CDROM", "DATABLOCK"][value]; - }, - "action": function(action, params) { obj = { diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index aaab2fc1c4..c5bc985d1b 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -523,7 +523,7 @@ function updateVMInfo(request,vm){ \ \ '+tr("Instance type")+'\ - '+vm_info.INSTANCE_TYPE+'\ + '+(vm_info.INSTANCE_TYPE ? vm_info.INSTANCE_TYPE : "--")+'\ \ \ '+tr("State")+'\ @@ -739,6 +739,7 @@ function popUpCreateVMDialog(){ if (!vm_name.length){ notifyError("Please specify a name for the virtual machine"); + return false; }; var vm = { @@ -1043,7 +1044,7 @@ function vncCallback(request,response){ function vncIcon(vm){ var graphics = vm.TEMPLATE.GRAPHICS; - var state = OCCI.Helper.resource_state("vm_lcm",vm.LCM_STATE); + var state = vm.STATE; var gr_icon; if (graphics && graphics.TYPE == "vnc" && state == "RUNNING"){ gr_icon = '
    '; diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index 5b7f768d40..b4542daa82 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -373,7 +373,7 @@ function updateImageInfo(request,img){ \ \ '+tr("Type")+'\ - '+OCCI.Helper.image_type(img_info.TYPE)+'\ + '+img_info.TYPE+'\ \ \ '+tr("Persistent")+'\ From aafd0087c2a0e9a33832628e05d8601eb6ebafd2 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 25 Jan 2012 23:46:58 +0100 Subject: [PATCH 30/64] Feature #1030: Allow parametric values when creating several VMs in Sunstone. --- src/sunstone/public/js/plugins/vms-tab.js | 36 +++++++++++++++++------ 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 43c71961be..fa69971dd6 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -75,13 +75,21 @@ var vms_tab_content = var create_vm_tmpl ='
    \
    \
    \ - \ -
    \ - \ -
    \ - \ - \ +
    \ + \ + \ +
    '+tr("Defaults to template name when emtpy")+'.
    \ +
    \ +
    \ + \ + \ +
    \ +
    \ + \ + \ +
    '+tr("You can use the wildcard %i. When creating several VMs, %i will be replaced with a different number starting from 0 in each of them")+'.
    \ +
    \
    \
    \
    \ @@ -846,6 +854,7 @@ function setupCreateVMDialog(){ }); $('button',dialog).button(); + setupTips(dialog); $('#create_vm_form',dialog).submit(function(){ var vm_name = $('#vm_name',this).val(); @@ -866,8 +875,16 @@ function setupCreateVMDialog(){ vm_name = $('#template_id option:selected',this).text(); }; - for (var i=0; i< n_times_int; i++){ - Sunstone.runAction("Template.instantiate",template_id,vm_name); + if (vm_name.indexOf("%i") == -1){ //no wildcard + for (var i=0; i< n_times_int; i++){ + Sunstone.runAction("Template.instantiate",template_id,vm_name); + }; + } else { //wildcard present: replace wildcard + var name = ""; + for (var i=0; i< n_times_int; i++){ + name = vm_name.replace(/%i/gi,i); + Sunstone.runAction("Template.instantiate",template_id,name); + }; }; Sunstone.runAction("VM.list"); @@ -1285,6 +1302,7 @@ $(document).ready(function(){ setupSaveasDialog(); setVMAutorefresh(); setupVNC(); + setupTips initCheckAllBoxes(dataTable_vMachines); tableCheckboxesListener(dataTable_vMachines); From 986c1282baaceeaf743e555a83d27283696e534b Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 25 Jan 2012 23:47:39 +0100 Subject: [PATCH 31/64] Feature #1030: Allow parametric values when creating several VMs in SelfService --- .../occi/lib/ui/public/js/plugins/compute.js | 25 ++++++++++++------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index 5550566e49..993faf93ab 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -89,8 +89,11 @@ var create_vm_tmpl ='\ \
    \
    \ - \ - \ +
    \ + \ + \ +
    '+tr("You can use the wildcard %i. When creating several VMs, %i will be replaced with a different number starting from 0 in each of them")+'.
    \ +
    \
    \
    \ \ @@ -686,6 +689,8 @@ function popUpCreateVMDialog(){ text: true }); + setupTips(dialog); + var net_select = makeSelectOptions(dataTable_vNetworks, 1,//id_col 2,//name_col @@ -772,17 +777,19 @@ function popUpCreateVMDialog(){ if (n_times.length){ n_times_int=parseInt(n_times,10); - } + }; - if (n_times_int>1){ - if (!vm_name.length){ - vm_name = $('#template_id option:selected',this).text(); - } + if (vm_name.indexOf("%i") == -1){ //no wildcard for (var i=0; i< n_times_int; i++){ Sunstone.runAction("VM.create",vm); }; - } else { - Sunstone.runAction("VM.create",vm); + } else { //wildcard present: replace wildcard + var name = ""; + for (var i=0; i< n_times_int; i++){ + name = vm_name.replace(/%i/gi,i); + vm["NAME"] = name; + Sunstone.runAction("VM.create",vm); + }; }; popUpVMDashboard(); From 00cf42e6b685a5ab26ca02d0eb142c311f56f6ee Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 30 Jan 2012 12:16:14 +0100 Subject: [PATCH 32/64] Feature #1069: Support secure-websocket-based VNC session in Sunstone. This commit adds support for using wss capabilities of websockify: * Add configuration option to Sunstone and saving/restore in user template support * Add new options to sunstone server configuration file * VNC session is started according to user setting * The code related to VNC proxy launch has been outsourced to OpenNebulaVNC.rb, so it can be mantained more easily and reused by, for example, SelfService. * Install novnc script has been corrected to point to "websockify" full path. Note: this commit changes vnc-related sunstone-server.conf keys and breaks vnc support in former versions of the configuration file. Update if necessary. --- install.sh | 3 +- share/install_novnc.sh | 3 +- src/sunstone/OpenNebulaVNC.rb | 90 ++++++++++++++++++++ src/sunstone/etc/sunstone-server.conf | 12 ++- src/sunstone/models/SunstoneServer.rb | 89 ++++++------------- src/sunstone/public/js/plugins/config-tab.js | 40 +++++++++ src/sunstone/public/js/plugins/vms-tab.js | 2 +- src/sunstone/sunstone-server.rb | 35 +++++++- 8 files changed, 205 insertions(+), 69 deletions(-) create mode 100644 src/sunstone/OpenNebulaVNC.rb diff --git a/install.sh b/install.sh index fb6452dba2..6a38084d7e 100755 --- a/install.sh +++ b/install.sh @@ -1075,7 +1075,8 @@ ETC_CLIENT_FILES="src/cli/etc/group.default" #----------------------------------------------------------------------------- SUNSTONE_FILES="src/sunstone/config.ru \ - src/sunstone/sunstone-server.rb" + src/sunstone/sunstone-server.rb \ + src/sunstone/OpenNebulaVNC.rb" SUNSTONE_BIN_FILES="src/sunstone/bin/sunstone-server" diff --git a/share/install_novnc.sh b/share/install_novnc.sh index 5dc90d6763..52dbf373ef 100755 --- a/share/install_novnc.sh +++ b/share/install_novnc.sh @@ -1,6 +1,7 @@ #!/bin/bash NOVNC_TMP=/tmp/one/novnc-$(date "+%Y%m%d%H%M%S") +PROXY_PATH=noVNC/utils/websockify if [ -z "$ONE_LOCATION" ]; then ONE_SHARE=/usr/share/one @@ -34,7 +35,7 @@ mv $ONE_SHARE/$dir $ONE_SHARE/noVNC mkdir -p $ONE_PUBLIC_SUNSTONE/vendor/noVNC mv $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/ -sed -i.bck "s%^\(:novnc_path: \).*$%\1$ONE_SHARE/noVNC%" $SUNSTONE_CONF +sed -i.bck "s%^\(:vnc_proxy_path: \).*$%\1$ONE_SHARE/$PROXY_PATH%" $SUNSTONE_CONF #Update file permissions chmod +x $ONE_SHARE/noVNC/utils/launch.sh diff --git a/src/sunstone/OpenNebulaVNC.rb b/src/sunstone/OpenNebulaVNC.rb new file mode 100644 index 0000000000..ecaac733b0 --- /dev/null +++ b/src/sunstone/OpenNebulaVNC.rb @@ -0,0 +1,90 @@ +# -------------------------------------------------------------------------- # +# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # +# # +# Licensed under the Apache License, Version 2.0 (the "License"); you may # +# not use this file except in compliance with the License. You may obtain # +# a copy of the License at # +# # +# http://www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# distributed under the License is distributed on an "AS IS" BASIS, # +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # +# See the License for the specific language governing permissions and # +# limitations under the License. # +#--------------------------------------------------------------------------- # + + +#This file provides support for launching and stopping a websockify proxy + +require 'json' + +class OpenNebulaVNC + def initialize(config,opt={:json_errors => true}) + @proxy_path = config[:vnc_proxy_path] + @proxy_base_port = config[:vnc_proxy_base_port].to_i + @wss = config[:vnc_proxy_support_wss] + $stderr.puts "wss #{@wss}" + @enable_wss = (@wss == "yes") || (@wss == "only") + @cert = @enable_wss? config[:vnc_proxy_cert] : nil + @key = @enable_wss? config[:vnc_proxy_key] : nil + @options=opt + end + + def error(code, msg) + if @options[:json_errors] + return [code,OpenNebula::Error.new(msg).to_json] + else + return [code,msg] + end + end + + def start(vm_resource) + if vm_resource['LCM_STATE'] != "3" + return error(403,"VM is not running") + end + + if vm_resource['TEMPLATE/GRAPHICS/TYPE'] != "vnc" + return error(403,"VM has no VNC configured") + end + + # The VM host and its VNC port + host = vm_resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME'] + vnc_port = vm_resource['TEMPLATE/GRAPHICS/PORT'] + # The port on which the proxy will listen + proxy_port = @proxy_base_port + vnc_port.to_i + + if !@proxy_path || @proxy_path.size == 0 + return error(403,"VNC proxy not configured") + end + + proxy_options = "" + + if @enable_wss + proxy_options += " --cert #{@cert}" + proxy_options += " --key #{@key}" if @key && @key.size > 0 + proxy_options += " --ssl-only" if @wss == "only" + end + + proxy_cmd = "#{@proxy_path} #{proxy_options} #{proxy_port} #{host}:#{vnc_port}" + + begin + $stderr.puts("Starting vnc proxy: #{proxy_cmd}") + pipe = IO.popen(proxy_cmd) + rescue Exception => e + error = Error.new(e.message) + return [500, error.to_json] + end + + vnc_pw = vm_resource['TEMPLATE/GRAPHICS/PASSWD'] + + info = {:pipe => pipe, :port => proxy_port, :password => vnc_pw} + return [200, info] + end + + #handle exceptions outside + def self.stop(pipe) + Process.kill('KILL',pipe.pid) + pipe.close + end +end diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf index 1927bfb949..349fa484c1 100644 --- a/src/sunstone/etc/sunstone-server.conf +++ b/src/sunstone/etc/sunstone-server.conf @@ -16,8 +16,18 @@ :core_auth: cipher # VNC Configuration +# base_port: base_port + vnc_port of the VM is the port where the +# proxy will listen for VNC session connections to that VM. +# vnc_proxy_path: path to the websockets proxy (set by install_novnc.sh) +# support_wss: "no", "yes", "only". For yes and only, provide path to +# cert and key. Note value must be a quoted string. +# (key is only necessary if not included in cert). :vnc_proxy_base_port: 29876 -:novnc_path: +:vnc_proxy_path: +:vnc_proxy_support_wss: "no" +:vnc_proxy_cert: +:vnc_proxy_key: + # Default language setting :lang: en_US diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index a8113bcf65..359a24267e 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -18,6 +18,7 @@ require 'OpenNebulaJSON' include OpenNebulaJSON require 'acct/watch_client' +require 'OpenNebulaVNC' class SunstoneServer # FLAG that will filter the elements retrieved from the Pools @@ -147,35 +148,35 @@ class SunstoneServer end ############################################################################ - # + # Unused ############################################################################ - def get_configuration(user_id) - if user_id != "0" - return [401, ""] - end + # def get_configuration(user_id) + # if user_id != "0" + # return [401, ""] + # end - one_config = VAR_LOCATION + "/config" - config = Hash.new + # one_config = VAR_LOCATION + "/config" + # config = Hash.new - begin - cfg = File.read(one_config) - rescue Exception => e - error = Error.new("Error reading config: #{e.inspect}") - return [500, error.to_json] - end + # begin + # cfg = File.read(one_config) + # rescue Exception => e + # error = Error.new("Error reading config: #{e.inspect}") + # return [500, error.to_json] + # end - cfg.lines do |line| - m=line.match(/^([^=]+)=(.*)$/) + # cfg.lines do |line| + # m=line.match(/^([^=]+)=(.*)$/) - if m - name=m[1].strip.upcase - value=m[2].strip - config[name]=value - end - end + # if m + # name=m[1].strip.upcase + # value=m[2].strip + # config[name]=value + # end + # end - return [200, config.to_json] - end + # return [200, config.to_json] + # end ############################################################################ # @@ -211,50 +212,16 @@ class SunstoneServer return [404, resource.to_json] end - if resource['LCM_STATE'] != "3" - error = OpenNebula::Error.new("VM is not running") - return [403, error.to_json] - end - - if resource['TEMPLATE/GRAPHICS/TYPE'] != "vnc" - error = OpenNebula::Error.new("VM has no VNC configured") - return [403, error.to_json] - end - - # The VM host and its VNC port - host = resource['/VM/HISTORY_RECORDS/HISTORY[last()]/HOSTNAME'] - vnc_port = resource['TEMPLATE/GRAPHICS/PORT'] - # The noVNC proxy_port - proxy_port = config[:vnc_proxy_base_port].to_i + vnc_port.to_i - - begin - novnc_cmd = "#{config[:novnc_path]}/utils/wsproxy.py" - novnc_exec = "#{novnc_cmd} #{proxy_port} #{host}:#{vnc_port}" - $stderr.puts("Starting vnc proxy: #{novnc_exec}") - pipe = IO.popen(novnc_exec) - rescue Exception => e - error = Error.new(e.message) - return [500, error.to_json] - end - - vnc_pw = resource['TEMPLATE/GRAPHICS/PASSWD'] - - info = {:pipe => pipe, :port => proxy_port, :password => vnc_pw} - return [200, info] + vnc_proxy = OpenNebulaVNC.new(config) + return vnc_proxy.start(resource) end ############################################################################ # ############################################################################ - def stopvnc(id,pipe) - resource = retrieve_resource("vm", id) - if OpenNebula.is_error?(resource) - return [404, resource.to_json] - end - + def stopvnc(pipe) begin - Process.kill('KILL',pipe.pid) - pipe.close + OpenNebulaVNC.stop(pipe) rescue Exception => e error = Error.new(e.message) return [500, error.to_json] diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js index 6f64a8bab4..126c509fcd 100644 --- a/src/sunstone/public/js/plugins/config-tab.js +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -33,6 +33,12 @@ var config_tab_content = \ \ \ + \ + ' + tr("Secure websockets connection") + '\ + \ + \ + \ + \ \ \
    \ @@ -48,6 +54,34 @@ var config_tab = { Sunstone.addMainTab('config_tab',config_tab); +function updateWss(){ + var user_info_req = { + data : { + id: uid, + }, + success: function(req,user_json) { + var template = user_json.USER.TEMPLATE; + var template_str=""; + template['VNC_WSS']= + $('#config_table #wss_checkbox').is(':checked') ? "yes" : "no"; + //convert json to ONE template format - simple conversion + $.each(template,function(key,value){ + template_str += (key + '=' + '"' + value + '"\n'); + }); + + var request = { + data: { + id: uid, + extra_param: template_str + }, + error: onError + }; + OpenNebula.User.update(request); + }, + }; + OpenNebula.User.show(user_info_req); +}; + $(document).ready(function(){ if (lang) $('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected'); @@ -55,4 +89,10 @@ $(document).ready(function(){ setLang($(this).val()); }); + $('table#config_table #wss_checkbox').change(updateWss); + + $.get('config/wss',function(response){ + if (response != "no") + $('table#config_table input#wss_checkbox').attr('checked','checked'); + }); }); \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index fa69971dd6..cfb477c9c7 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -1227,7 +1227,7 @@ function setupVNC(){ function vncCallback(request,response){ rfb = new RFB({'target': $D('VNC_canvas'), - 'encrypt': false, + 'encrypt': $('#config_table #wss_checkbox').is(':checked'), 'true_color': true, 'local_cursor': true, 'shared': true, diff --git a/src/sunstone/sunstone-server.rb b/src/sunstone/sunstone-server.rb index 4f32a63433..05b80c09d7 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -39,6 +39,7 @@ SUNSTONE_ROOT_DIR = File.dirname(__FILE__) $: << RUBY_LIB_LOCATION $: << RUBY_LIB_LOCATION+'/cloud' +$: << SUNSTONE_ROOT_DIR $: << SUNSTONE_ROOT_DIR+'/models' ############################################################################## @@ -115,12 +116,27 @@ helpers do session[:ip] = request.ip session[:remember] = params[:remember] + #User IU options initialization + #Load options either from user settings or default config. + # - LANG + # - WSS CONECTION + if user['TEMPLATE/LANG'] session[:lang] = user['TEMPLATE/LANG'] else session[:lang] = settings.config[:lang] end + if user['TEMPLATE/VNC_WSS'] + session[:wss] = user['TEMPLATE/VNC_WSS'] + else + session[:wss] = settings.config[:vnc_proxy_support_wss] + #limit to yes,no options + session[:wss] = (session[:wss] != "no" ? "yes" : "no") + end + + #end user options + if params[:remember] env['rack.session.options'][:expire_after] = 30*60*60*24 end @@ -212,8 +228,16 @@ end ############################################################################## # Config and Logs ############################################################################## -get '/config' do - @SunstoneServer.get_configuration(session[:user_id]) +#get '/config' do +# @SunstoneServer.get_configuration(session[:user_id]) +#end + +get '/config/:opt' do + case params[:opt] + when "lang" then session[:lang] + when "wss" then session[:wss] + else "unknown" + end end post '/config' do @@ -226,6 +250,7 @@ post '/config' do body.each do | key,value | case key when "lang" then session[:lang]=value + when "wss" then session[:wss]=value end end end @@ -301,7 +326,8 @@ post '/vm/:id/stopvnc' do return [403, OpenNebula::Error.new(msg).to_json] end - rc = @SunstoneServer.stopvnc(vm_id, vnc_hash[vm_id][:pipe]) + rc = @SunstoneServer.stopvnc(vnc_hash[vm_id][:pipe]) + if rc[0] == 200 session['vnc'].delete(vm_id) end @@ -327,7 +353,8 @@ post '/vm/:id/startvnc' do return [200, info.to_json] end - rc = @SunstoneServer.startvnc(vm_id, settings.config) + rc = @SunstoneServer.startvnc(vm_id,settings.config) + if rc[0] == 200 info = rc[1] session['vnc'][vm_id] = info.clone From f9b9f1a0cd9b492239411d2150834e00291540b0 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 2 Feb 2012 10:22:34 +0100 Subject: [PATCH 33/64] Bug #1085: Increase cookie expiration time in web-UIs. Skewed clocks can cause that cookie does not work. Expiration time increased from 1 to 10 minutes, which is the same as the default duration of the session. --- src/cloud/occi/lib/occi-server.rb | 2 +- src/ozones/Server/ozones-server.rb | 2 +- src/sunstone/sunstone-server.rb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index 5eb9a97846..470ec9e19a 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -340,7 +340,7 @@ get '/ui' do return File.read(File.dirname(__FILE__)+'/ui/templates/login.html') end - time = Time.now + 60 + time = Time.now + 60*10 response.set_cookie("occi-user", :value=>"#{session[:user]}", :expires=>time) diff --git a/src/ozones/Server/ozones-server.rb b/src/ozones/Server/ozones-server.rb index e7cb7ab908..84dc77d9b7 100755 --- a/src/ozones/Server/ozones-server.rb +++ b/src/ozones/Server/ozones-server.rb @@ -192,7 +192,7 @@ get '/' do return File.read(File.dirname(__FILE__)+ '/templates/login.html') unless authorized? - time = Time.now + 60 + time = Time.now + 60*10 response.set_cookie("ozones-user", :value=>"#{session[:user]}", :expires=>time) diff --git a/src/sunstone/sunstone-server.rb b/src/sunstone/sunstone-server.rb index 05b80c09d7..2e22b2aa3f 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -185,7 +185,7 @@ get '/' do return File.read(File.dirname(__FILE__)+'/templates/'+templ) end - time = Time.now + 60 + time = Time.now + 60*10 response.set_cookie("one-user", :value=>"#{session[:user]}", :expires=>time) From 76506b57377bc5d8ed4a798ac0ada1d8aad7dcb6 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 2 Feb 2012 11:02:54 +0100 Subject: [PATCH 34/64] feature #1030: add %i wildcard support to cli when instantiating multiple VMs. --- src/cli/one_helper/onetemplate_helper.rb | 6 +++++- src/cli/onetemplate | 5 +++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cli/one_helper/onetemplate_helper.rb b/src/cli/one_helper/onetemplate_helper.rb index 8b56fbe2c4..308d3a9193 100644 --- a/src/cli/one_helper/onetemplate_helper.rb +++ b/src/cli/one_helper/onetemplate_helper.rb @@ -22,7 +22,11 @@ class OneTemplateHelper < OpenNebulaHelper::OneHelper :short => "-n vm_name", :large => "--name vm_name", :format => String, - :description => "Name of the new Virtual Machine" + :description => <<-EOT +Name of the new Virtual Machine. When instantiating + multiple VMs you can use the\"%i\" wildcard to produce + different names such as vm-0, vm-1... +EOT } MULTIPLE={ diff --git a/src/cli/onetemplate b/src/cli/onetemplate index a75b4352b0..7a27e194fa 100755 --- a/src/cli/onetemplate +++ b/src/cli/onetemplate @@ -108,9 +108,10 @@ cmd=CommandParser::CmdParser.new(ARGV) do exit_code=0 number = options[:multiple] || 1 - number.times do + number.times do |i| exit_code=helper.perform_action(args[0],options,"instantiated") do |t| - res = t.instantiate(options[:vm_name]) + name = options[:vm_name].gsub("%i",i.to_s) + res = t.instantiate(name) if !OpenNebula.is_error?(res) puts "VM ID: #{res}" From 7f485ad179311a3d30b7f366bc850692c697be1f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 7 Feb 2012 17:21:30 +0100 Subject: [PATCH 35/64] Bug #1110: Add VMware IM,TM and VMM drivers to Sunstone host creation dialog. --- src/sunstone/public/js/plugins/hosts-tab.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 77db99cb93..bffa341124 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -67,6 +67,7 @@ var create_host_tmpl = \ @@ -76,6 +77,7 @@ var create_host_tmpl = \ @@ -95,6 +97,7 @@ var create_host_tmpl = \
    \ From 22b888e2ebadebbb8acd2149c2da3460f6f782bd Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 7 Feb 2012 18:25:42 +0100 Subject: [PATCH 36/64] Bug #1111: Improve constraints when creating a ranged virtual network. --- src/sunstone/public/js/plugins/vnets-tab.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 66856161ce..87a153b4e9 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -822,8 +822,8 @@ function setupCreateVNetDialog() { var ip_start = $('#ip_start',this).val(); var ip_end = $('#ip_end',this).val(); - if (!network_addr.length){ - notifyError(tr("Please provide a network address")); + if (!(ip_start.length && ip_end.length) && !network_addr.length){ + notifyError(tr("There are missing network parameters")); return false; }; @@ -832,11 +832,15 @@ function setupCreateVNetDialog() { "vnet" : { "type" : "RANGED", "bridge" : bridge, - "network_mask" : network_mask, - "network_address" : network_addr, "name" : name } }; + if (network_addr.length) + network_json["vnet"]["network_address"]=network_addr; + + if (network_mask.length) + network_json["vnet"]["network_mask"]=network_mask; + if (custom){ if (ip_start.length) network_json["vnet"]["ip_start"] = ip_start; From 1cd6406dc587b9e2ffa1d82cd52e3e5bb76f8ef5 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 9 Feb 2012 18:57:47 +0100 Subject: [PATCH 37/64] Feature #1030: Fix onetemplate when no name is provided --- src/cli/onetemplate | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cli/onetemplate b/src/cli/onetemplate index 7a27e194fa..6016027f02 100755 --- a/src/cli/onetemplate +++ b/src/cli/onetemplate @@ -110,7 +110,8 @@ cmd=CommandParser::CmdParser.new(ARGV) do number = options[:multiple] || 1 number.times do |i| exit_code=helper.perform_action(args[0],options,"instantiated") do |t| - name = options[:vm_name].gsub("%i",i.to_s) + name = options[:vm_name] + name = name.gsub("%i",i.to_s) if name res = t.instantiate(name) if !OpenNebula.is_error?(res) From 6bb9cb74a22c0efbc7d51a949bea2d51c52a8dee Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 13 Feb 2012 15:51:55 +0100 Subject: [PATCH 38/64] Feature #1069: Improvements for wss support and configuration in Sunstone. Allow non quoted yes | no values in configuration. Set wss configuration choice for the session so it stays if page reloaded --- src/sunstone/OpenNebulaVNC.rb | 3 +-- src/sunstone/etc/sunstone-server.conf | 10 ++++++---- src/sunstone/public/js/plugins/config-tab.js | 1 + src/sunstone/sunstone-server.rb | 5 +++-- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/sunstone/OpenNebulaVNC.rb b/src/sunstone/OpenNebulaVNC.rb index ecaac733b0..e2e3ac3fde 100644 --- a/src/sunstone/OpenNebulaVNC.rb +++ b/src/sunstone/OpenNebulaVNC.rb @@ -24,8 +24,7 @@ class OpenNebulaVNC @proxy_path = config[:vnc_proxy_path] @proxy_base_port = config[:vnc_proxy_base_port].to_i @wss = config[:vnc_proxy_support_wss] - $stderr.puts "wss #{@wss}" - @enable_wss = (@wss == "yes") || (@wss == "only") + @enable_wss = (@wss == "yes") || (@wss == "only") || (@wss == true) @cert = @enable_wss? config[:vnc_proxy_cert] : nil @key = @enable_wss? config[:vnc_proxy_key] : nil @options=opt diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf index 349fa484c1..bcc7e8225f 100644 --- a/src/sunstone/etc/sunstone-server.conf +++ b/src/sunstone/etc/sunstone-server.conf @@ -19,12 +19,14 @@ # base_port: base_port + vnc_port of the VM is the port where the # proxy will listen for VNC session connections to that VM. # vnc_proxy_path: path to the websockets proxy (set by install_novnc.sh) -# support_wss: "no", "yes", "only". For yes and only, provide path to -# cert and key. Note value must be a quoted string. -# (key is only necessary if not included in cert). +# support_wss: no | yes | only. For yes and only, provide path to +# cert and key. "yes" means both ws and wss connections will be +# supported. +# vnc_proxy_cert: Certificate to encrypt wss connections. +# vnc_proxy_key: Key for wss connections. Only necessary if not included in cert. :vnc_proxy_base_port: 29876 :vnc_proxy_path: -:vnc_proxy_support_wss: "no" +:vnc_proxy_support_wss: no :vnc_proxy_cert: :vnc_proxy_key: diff --git a/src/sunstone/public/js/plugins/config-tab.js b/src/sunstone/public/js/plugins/config-tab.js index 126c509fcd..f342e91665 100644 --- a/src/sunstone/public/js/plugins/config-tab.js +++ b/src/sunstone/public/js/plugins/config-tab.js @@ -80,6 +80,7 @@ function updateWss(){ }, }; OpenNebula.User.show(user_info_req); + $.post('config',JSON.stringify({wss : ($('#config_table #wss_checkbox').is(':checked') ? "yes" : "no")})); }; $(document).ready(function(){ diff --git a/src/sunstone/sunstone-server.rb b/src/sunstone/sunstone-server.rb index 2e22b2aa3f..bb9bdeba03 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -130,9 +130,10 @@ helpers do if user['TEMPLATE/VNC_WSS'] session[:wss] = user['TEMPLATE/VNC_WSS'] else - session[:wss] = settings.config[:vnc_proxy_support_wss] + wss = settings.config[:vnc_proxy_support_wss] #limit to yes,no options - session[:wss] = (session[:wss] != "no" ? "yes" : "no") + session[:wss] = (wss == true || wss == "yes" || wss == "only" ? + "yes" : "no") end #end user options From 4ccaf9704a5d415e4979bbf53dce263d2c1e7cdb Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 13 Feb 2012 15:55:11 +0100 Subject: [PATCH 39/64] Feature #1076: Add VNC support in SelfService. When enabled in the occi server configuration file, UI users will be able to click the VNC icon that appears in the VM information. Then the websockets proxy will be set up, provided that the machine has been configured with the appropiate GRAPHICS section etc. This must be done in the OCCI templates, and cannot be done by the UI user. Wss sessions can be configured in the occi server configuration file. Unlike Sunstone, here they are transparent to the user and whenever they are enabled VNC sessions will be launched using wss:// automaticly. As such, it is not up to the user to choose the type of connection, and it fully depends on the server configuration. Additionally the install_novnc.sh script has been updated and improved. The install.sh has been updated too. --- install.sh | 3 +- share/install_novnc.sh | 31 ++++++--- src/cloud/occi/etc/occi-server.conf | 23 ++++++- src/cloud/occi/lib/OCCIServer.rb | 32 ++++++++- src/cloud/occi/lib/occi-server.rb | 69 ++++++++++++++++++- src/cloud/occi/lib/ui/public/js/locale.js | 2 +- src/cloud/occi/lib/ui/public/js/occi.js | 9 ++- .../occi/lib/ui/public/js/plugins/compute.js | 42 ++++++++--- .../lib/ui/public/js/plugins/configuration.js | 25 +++++-- 9 files changed, 205 insertions(+), 31 deletions(-) diff --git a/install.sh b/install.sh index 9c10727ba6..d5ce330bcb 100755 --- a/install.sh +++ b/install.sh @@ -1012,7 +1012,8 @@ OCCI_LIB_FILES="src/cloud/occi/lib/OCCIServer.rb \ src/cloud/occi/lib/UserOCCI.rb \ src/cloud/occi/lib/UserPoolOCCI.rb \ src/cloud/occi/lib/ImageOCCI.rb \ - src/cloud/occi/lib/ImagePoolOCCI.rb" + src/cloud/occi/lib/ImagePoolOCCI.rb \ + src/sunstone/OpenNebulaVNC.rb" OCCI_LIB_CLIENT_FILES="src/cloud/occi/lib/OCCIClient.rb" diff --git a/share/install_novnc.sh b/share/install_novnc.sh index 52dbf373ef..861fe78315 100755 --- a/share/install_novnc.sh +++ b/share/install_novnc.sh @@ -7,35 +7,50 @@ if [ -z "$ONE_LOCATION" ]; then ONE_SHARE=/usr/share/one ONE_PUBLIC_SUNSTONE=/usr/lib/one/sunstone/public SUNSTONE_CONF=/etc/one/sunstone-server.conf + ONE_PUBLIC_SELFSERVICE=/usr/lib/one/ruby/cloud/occi/ui/public + SELFSERVICE_CONF=/etc/one/occi-server.conf else ONE_SHARE=$ONE_LOCATION/share ONE_PUBLIC_SUNSTONE=$ONE_LOCATION/lib/sunstone/public SUNSTONE_CONF=$ONE_LOCATION/etc/sunstone-server.conf + ONE_PUBLIC_SELFSERVICE=$ONE_LOCATION/lib/ruby/cloud/occi/ui/public + SELFSERVICE_CONF=$ONE_LOCATION/etc/occi-server.conf fi +echo "Downloading noVNC latest version..." mkdir -p $NOVNC_TMP -wget -P $NOVNC_TMP --no-check-certificate http://github.com/kanaka/noVNC/tarball/master - +cd $NOVNC_TMP +curl -O -# -L http://github.com/kanaka/noVNC/tarball/master if [ $? -ne 0 ]; then - echo "Error downloading noVNC" + echo "\nError downloading noVNC" exit 1 fi +echo "Extracting files to temporary folder..." tar=`ls -rt $NOVNC_TMP|tail -n1` -tar -C $ONE_SHARE -mxvzf $NOVNC_TMP/$tar +tar -C $ONE_SHARE -mxzf $NOVNC_TMP/$tar if [ $? -ne 0 ]; then echo "Error untaring noVNC" exit 1 fi +echo "Moving files to OpenNebula $ONE_SHARE folder..." +rm -rf $ONE_SHARE/noVNC dir=`ls -rt $ONE_SHARE|tail -n1` mv $ONE_SHARE/$dir $ONE_SHARE/noVNC +echo "Installing Sunstone client libraries in $ONE_PUBLIC_SUNSTONE..." mkdir -p $ONE_PUBLIC_SUNSTONE/vendor/noVNC -mv $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/ +cp -r $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SUNSTONE/vendor/noVNC/ -sed -i.bck "s%^\(:vnc_proxy_path: \).*$%\1$ONE_SHARE/$PROXY_PATH%" $SUNSTONE_CONF +echo "Installing SelfService client libraries in $ONE_PUBLIC_SELFSERVICE..." +mkdir -p $ONE_PUBLIC_SELFSERVICE/vendor/noVNC +cp -r $ONE_SHARE/noVNC/include/ $ONE_PUBLIC_SELFSERVICE/vendor/noVNC/ -#Update file permissions -chmod +x $ONE_SHARE/noVNC/utils/launch.sh +echo "Backing up and updating $SUNSTONE_CONF with new VNC proxy path..." +sed -i.bck "s%^\(:vnc_proxy_path:\).*$%\1 $ONE_SHARE/$PROXY_PATH%" $SUNSTONE_CONF +echo "Backing up and updating $SELFSERVICE_CONF with new VNC proxy path..." +sed -i.bck "s%^\(:vnc_proxy_path:\).*$%\1 $ONE_SHARE/$PROXY_PATH%" $SELFSERVICE_CONF + +echo "Installation successful" \ No newline at end of file diff --git a/src/cloud/occi/etc/occi-server.conf b/src/cloud/occi/etc/occi-server.conf index 0084890209..90ea4df134 100644 --- a/src/cloud/occi/etc/occi-server.conf +++ b/src/cloud/occi/etc/occi-server.conf @@ -52,5 +52,26 @@ :cpu: 8 :memory: 8192 -# Default language setting for Self-Service UI + +############################################################# +### SelfService UI Settings +############################################################# + +# Default language setting :lang: en_US + +# VNC Configuration +# vnc_enable: yes | no. Allow users to launch vnc sessions. +# base_port: base_port + vnc_port of the VM is the port where the +# proxy will listen for VNC session connections to that VM. +# vnc_proxy_path: path to the websockets proxy (set by install_novnc.sh) +# support_wss: no | yes | only. If yes or only provide path to cert and key. +# "yes" means the proxy will accept both ws and wss connections. +# vnc_proxy_cert: Certificate to encrypt wss connections. +# vnc_proxy_key: Key for wss connections. Only necessary if not included in cert. +:vnc_enable: no +:vnc_proxy_base_port: 33876 +:vnc_proxy_path: +:vnc_proxy_support_wss: no +:vnc_proxy_cert: +:vnc_proxy_key: diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index fbe3d210a9..d6c8691b96 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -30,6 +30,8 @@ require 'ImagePoolOCCI' require 'UserOCCI' require 'UserPoolOCCI' +require 'OpenNebulaVNC' + require 'pp' @@ -236,7 +238,6 @@ class OCCIServer < CloudServer return to_occi_xml(vm, 200) end - # Deletes a COMPUTE resource # request:: _Hash_ hash containing the data of the request # [return] _String_,_Integer_ Delete confirmation msg or error, @@ -505,4 +506,33 @@ class OCCIServer < CloudServer return to_occi_xml(user, 200) end + + ############################################################################ + # VNC Methods + ############################################################################ + + def startvnc(id,config) + vm = VirtualMachineOCCI.new( + VirtualMachine.build_xml(id), + @client) + + rc = vm.info + if OpenNebula.is_error?(rc) + error = "Error starting VNC session, " + error += "could not retrieve Virtual Machine" + return [404,error] + end + + vnc_proxy = OpenNebulaVNC.new(config,{:json_errors => false}) + return vnc_proxy.start(vm) + end + + def stopvnc(pipe) + begin + OpenNebulaVNC.stop(pipe) + rescue Exception => e + return [500, e.message] + end + return [200,nil] + end end diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index 470ec9e19a..b64016525d 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -309,7 +309,19 @@ end ## UI ############################################## -post '/config' do +get '/ui/config/:opt' do + case params[:opt] + when "lang" then session[:lang] + when "wss" + wss = settings.config[:vnc_proxy_support_wss] + wss = (wss == true || wss == "yes" || wss == "only" ? "yes" : "no") + return wss + when "vnc" then settings.config[:vnc_enable] ? "yes" : "no" + else [404, "Unknown configuration option"] + end +end + +post '/ui/config' do begin body = JSON.parse(request.body.read) rescue @@ -321,6 +333,7 @@ post '/config' do when "lang" then session[:lang]=value end end + return 200 end get '/ui/login' do @@ -355,3 +368,57 @@ post '/ui/upload' do result,rc = @occi_server.post_storage(request) treat_response(result,rc) end + +post '/ui/startvnc/:id' do + if !settings.config[:vnc_enable] + return [403, "VNC sessions are disabled"] + end + + vm_id = params[:id] + + vnc_hash = session['vnc'] + + if !vnc_hash + session['vnc']= {} + elsif vnc_hash[vm_id] + #return existing information + info = vnc_hash[vm_id].clone + info.delete(:pipe) + + return [200, info.to_json] + end + + rc = @occi_server.startvnc(vm_id, settings.config) + + if rc[0] == 200 + info = rc[1] + session['vnc'][vm_id] = info.clone + info.delete(:pipe) + + [200, info.to_json] + else + rc + end +end + +post '/ui/stopvnc/:id' do + if !settings.config[:vnc_enable] + return [403, "VNC sessions are disabled"] + end + + vm_id = params[:id] + vnc_hash = session['vnc'] + + if !vnc_hash || !vnc_hash[vm_id] + msg = "It seems there is no VNC proxy running for this machine" + return [403, msg] + end + + rc = @occi_server.stopvnc(vnc_hash[vm_id][:pipe]) + + if rc[0] == 200 + session['vnc'].delete(vm_id) + end + + rc +end diff --git a/src/cloud/occi/lib/ui/public/js/locale.js b/src/cloud/occi/lib/ui/public/js/locale.js index be816c7239..792772954f 100644 --- a/src/cloud/occi/lib/ui/public/js/locale.js +++ b/src/cloud/occi/lib/ui/public/js/locale.js @@ -45,7 +45,7 @@ function setLang(lang_str){ if (('localStorage' in window) && (window['localStorage'] !== null)){ localStorage['lang']=lang_str; }; - $.post('config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"}); + $.post('ui/config',JSON.stringify({lang:lang_str}),function(){window.location.href = "./ui"}); }; $(document).ready(function(){ diff --git a/src/cloud/occi/lib/ui/public/js/occi.js b/src/cloud/occi/lib/ui/public/js/occi.js index 004938dc67..569a75e527 100644 --- a/src/cloud/occi/lib/ui/public/js/occi.js +++ b/src/cloud/occi/lib/ui/public/js/occi.js @@ -413,7 +413,7 @@ var OCCI = { params.data.body = ''; OCCI.Action.update(params,OCCI.VM.resource,"saveas"); }, -/* "vnc" : function(params,startstop){ + "vnc" : function(params,startstop){ var callback = params.success; var callback_error = params.error; var id = params.data.id; @@ -423,7 +423,7 @@ var OCCI = { var action = OCCI.Helper.action(method); var request = OCCI.Helper.request(resource,method, id); $.ajax({ - url: "vm/" + id + "/" + method, + url: "ui/" + method + "/" + id, type: "POST", dataType: "json", success: function(response){ @@ -440,13 +440,16 @@ var OCCI = { }, "stopvnc" : function(params){ OCCI.VM.vnc(params,"stopvnc"); + }, +/* "monitor" : function(params){ OCCI.Action.monitor(params,OCCI.VM.resource,false); }, "monitor_all" : function(params){ OCCI.Action.monitor(params,OCCI.VM.resource,true); - }*/ + } +*/ }, "Image": { diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index 993faf93ab..5613a1b3a2 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -15,16 +15,19 @@ /* -------------------------------------------------------------------------- */ /*Virtual Machines tab plugin*/ -//var INCLUDE_URI = "vendor/noVNC/include/"; +var INCLUDE_URI = "vendor/noVNC/include/"; //var VM_HISTORY_LENGTH = 40; -/* + function loadVNC(){ var script = ''; document.write(script); } loadVNC(); +var vnc_enable=false; +var use_wss=false; +/* var vm_graphs = [ { title : tr("CPU"), monitor_resources : "cpu_usage", @@ -264,7 +267,6 @@ var vm_actions = { error: onError }, - /* "VM.startvnc" : { type: "single", call: OCCI.VM.startvnc, @@ -280,6 +282,7 @@ var vm_actions = { notify: true }, +/* "VM.monitor" : { type: "monitor", call : OCCI.VM.monitor, @@ -540,6 +543,10 @@ function updateVMInfo(request,vm){ '+tr("Memory")+'\ '+vm_info.MEMORY+'\ \ + \ + '+tr("Launch VNC session")+'\ + '+vncIcon(vm_info)+'\ + \ \ \
    \ @@ -940,7 +947,7 @@ function setVMAutorefresh(){ },INTERVAL+someTime()); } -/* + function updateVNCState(rfb, state, oldstate, msg) { var s, sb, cad, klass; s = $D('VNC_status'); @@ -1016,7 +1023,7 @@ function setupVNC(){ Sunstone.runAction("VM.stopvnc",id); }); - $('.vnc',main_tabs_context).live("click",function(){ + $('.vnc').live("click",function(){ //Which VM is it? var id = $(this).attr('vm_id'); //Set attribute to dialog @@ -1029,7 +1036,7 @@ function setupVNC(){ function vncCallback(request,response){ rfb = new RFB({'target': $D('VNC_canvas'), - 'encrypt': false, + 'encrypt': use_wss, 'true_color': true, 'local_cursor': true, 'shared': true, @@ -1049,6 +1056,20 @@ function vncCallback(request,response){ } +function vncIcon(vm){ + var gr_icon; + if (vnc_enable){ + gr_icon = ''; + gr_icon += '\"'+tr("Open'; + } + else { + gr_icon = '\"'+tr("VNC'; + } + return gr_icon; +} + +/* + function vncIcon(vm){ var graphics = vm.TEMPLATE.GRAPHICS; var state = vm.STATE; @@ -1063,6 +1084,9 @@ function vncIcon(vm){ return gr_icon; } +*/ + +/* function vmMonitorError(req,error_json){ var message = error_json.error.message; var info = req.request.data[0].monitor; @@ -1070,9 +1094,9 @@ function vmMonitorError(req,error_json){ var id_suffix = labels.replace(/,/g,'_'); var id = '#vm_monitor_'+id_suffix; $('#vm_monitoring_tab '+id).html('
    '+message+'
    '); -} +}*/ + -*/ // At this point the DOM is ready and the sunstone.js ready() has been run. $(document).ready(function(){ @@ -1102,7 +1126,7 @@ $(document).ready(function(){ //setupCreateVMDialog(); setupSaveasDialog(); setVMAutorefresh(); - //setupVNC(); + setupVNC(); initCheckAllBoxes(dataTable_vMachines); tableCheckboxesListener(dataTable_vMachines); diff --git a/src/cloud/occi/lib/ui/public/js/plugins/configuration.js b/src/cloud/occi/lib/ui/public/js/plugins/configuration.js index c92844ac1e..de32d3e084 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/configuration.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/configuration.js @@ -49,16 +49,29 @@ var config_tab = { Sunstone.addMainTab('config_tab',config_tab); $(document).ready(function(){ - if (lang) - $('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected'); - $('table#config_table #lang_sel').change(function(){ - setLang($(this).val()); - }); - $('#li_config_tab').click(function(){ hideDialog(); }); + //Set lang to the right value + if (lang) + $('table#config_table #lang_sel option[value="'+lang+'"]').attr('selected','selected'); + + //Listen to changes in language + $('table#config_table #lang_sel').change(function(){ + setLang($(this).val()); + }); + + //Vendor customization, change small logo $('div#logo img').attr('src',logo_small); + $.get('ui/config/vnc',function(response){ + if (response == "true" || response == "yes") + vnc_enable=true; //defined in compute.js + }); + + $.get('ui/config/wss', function(response){ + if (response == "true" || response == "yes") + use_wss=true; //defined in compute.js + }); }); \ No newline at end of file From 2630d1c6a7a630b26646107f88c33e2ae1500671 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 14 Feb 2012 18:59:00 +0100 Subject: [PATCH 40/64] Improve Selfservice/OCCI upload. Wait until images have been successfully copied into the repository by opennebula to return from request. --- src/cloud/occi/lib/OCCIServer.rb | 11 ++++++++++- src/cloud/occi/lib/occi-server.rb | 6 +----- src/cloud/occi/lib/ui/public/js/plugins/storage.js | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/cloud/occi/lib/OCCIServer.rb b/src/cloud/occi/lib/OCCIServer.rb index f762fe1fbc..1a1a6357d1 100755 --- a/src/cloud/occi/lib/OCCIServer.rb +++ b/src/cloud/occi/lib/OCCIServer.rb @@ -45,6 +45,9 @@ COLLECTIONS = ["compute", "instance_type", "network", "storage"] # FLAG that will filter the elements retrieved from the Pools POOL_FILTER = Pool::INFO_ALL +# Secs to sleep between checks to see if image upload© to repo is finished +IMAGE_POLL_SLEEP_TIME = 1 + class OCCIServer < CloudServer # Server initializer # config_file:: _String_ path of the config file @@ -410,8 +413,14 @@ class OCCIServer < CloudServer return rc, CloudServer::HTTP_ERROR_CODE[rc.errno] end - # --- Prepare XML Response --- image.info + #wait until image is ready to return + while (image.state_str == 'LOCKED') && (image['RUNNING_VMS'] == '0') do + sleep IMAGE_POLL_SLEEP_TIME + image.info + end + + # --- Prepare XML Response --- return to_occi_xml(image, :status=>201) end diff --git a/src/cloud/occi/lib/occi-server.rb b/src/cloud/occi/lib/occi-server.rb index ad51901120..8bee03b296 100755 --- a/src/cloud/occi/lib/occi-server.rb +++ b/src/cloud/occi/lib/occi-server.rb @@ -366,13 +366,9 @@ get '/ui' do end post '/ui/upload' do - file = Tempfile.new('uploaded_image') - FileUtils.cp(request.env['rack.input'].path, file.path) - #so we can re-use occi post_storage() - request.params['file'] = {:tempfile => file} + request.params['file'] = {:tempfile => request.env['rack.input']} result,rc = @occi_server.post_storage(request) - treat_response(result,rc) end diff --git a/src/cloud/occi/lib/ui/public/js/plugins/storage.js b/src/cloud/occi/lib/ui/public/js/plugins/storage.js index 6e7b99d7fd..336a51d272 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -478,7 +478,7 @@ function popUpCreateImageDialog(){ multiple: false, params: {}, showMessage: function(message){ - notifyMessage(message); + //notifyMessage(message); }, onSubmit: function(id, fileName){ var xml = json2xml(img_obj,"STORAGE"); From 5dbf040f9c91d3a965aab13e5e39e130a5b5e4f1 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 15 Feb 2012 14:10:24 +0100 Subject: [PATCH 41/64] Feature #1089: Upload support for images in Sunstone. Follows the same principles as SelfService. --- install.sh | 2 + src/sunstone/models/SunstoneServer.rb | 30 +++++ src/sunstone/public/js/plugins/images-tab.js | 115 +++++++++++++++++-- src/sunstone/sunstone-server.rb | 7 ++ src/sunstone/views/index.erb | 1 + 5 files changed, 143 insertions(+), 12 deletions(-) diff --git a/install.sh b/install.sh index b0d21b42ff..fa2b593fe0 100755 --- a/install.sh +++ b/install.sh @@ -265,6 +265,7 @@ SUNSTONE_DIRS="$SUNSTONE_LOCATION/models \ $SUNSTONE_LOCATION/public/vendor/jQuery \ $SUNSTONE_LOCATION/public/vendor/jGrowl \ $SUNSTONE_LOCATION/public/vendor/flot \ + $SUNSTONE_LOCATION/public/vendor/fileuploader \ $SUNSTONE_LOCATION/public/images \ $SUNSTONE_LOCATION/templates \ $SUNSTONE_LOCATION/views" @@ -455,6 +456,7 @@ INSTALL_SUNSTONE_FILES=( SUNSTONE_PUBLIC_VENDOR_JQUERYUIIMAGES:$SUNSTONE_LOCATION/public/vendor/jQueryUI/images SUNSTONE_PUBLIC_VENDOR_JQUERYLAYOUT:$SUNSTONE_LOCATION/public/vendor/jQueryLayout SUNSTONE_PUBLIC_VENDOR_FLOT:$SUNSTONE_LOCATION/public/vendor/flot + SUNSTONE_PUBLIC_VENDOR_FILEUPLOADER:$SUNSTONE_LOCATION/public/vendor/fileuploader SUNSTONE_PUBLIC_IMAGES_FILES:$SUNSTONE_LOCATION/public/images SUNSTONE_PUBLIC_LOCALE_EN_US:$SUNSTONE_LOCATION/public/locale/en_US SUNSTONE_PUBLIC_LOCALE_RU:$SUNSTONE_LOCATION/public/locale/ru diff --git a/src/sunstone/models/SunstoneServer.rb b/src/sunstone/models/SunstoneServer.rb index c4049404e6..5829b95c4d 100644 --- a/src/sunstone/models/SunstoneServer.rb +++ b/src/sunstone/models/SunstoneServer.rb @@ -19,11 +19,16 @@ include OpenNebulaJSON require 'acct/watch_client' require 'OpenNebulaVNC' +require 'OpenNebulaJSON/JSONUtils' +include JSONUtils class SunstoneServer # FLAG that will filter the elements retrieved from the Pools POOL_FILTER = Pool::INFO_ALL + # Secs to sleep between checks to see if image upload to repo is finished + IMAGE_POLL_SLEEP_TIME = 5 + def initialize(client) @client = client end @@ -113,6 +118,31 @@ class SunstoneServer end end + ############################################################################ + # + ############################################################################ + def upload(template, file_path) + image_hash = parse_json(template, 'image') + image_hash['PATH'] = file_path + + new_template = {:image => image_hash}.to_json + image = ImageJSON.new(Image.build_xml, @client) + + rc = image.create(new_template) + + if OpenNebula.is_error?(rc) + return [500, rc.to_json] + end + + image.info + #wait until image is ready to return + while (image.state_str == 'LOCKED') && (image['RUNNING_VMS'] == '0') do + sleep IMAGE_POLL_SLEEP_TIME + image.info + end + return [201, image.to_json] + end + ############################################################################ # ############################################################################ diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 62ab9f159c..02e441da56 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -100,14 +100,21 @@ var create_image_tmpl = \
    \
    \ - \ + \ +\ \
    \ +\ \
    \ +\ + \ +
    \ +\ \ \
    '+tr("Please choose path if you have a file-based image. Choose source otherwise or create an empty datablock disk.")+'

    \ +\
    \
    \ \ @@ -129,6 +136,11 @@ var create_image_tmpl = \
    '+tr("Type of file system to be built. This can be any value understood by mkfs unix command.")+'
    \
    \ +
    \ + \ +
    \ +
    \ +
    \
    \
    \
    \ @@ -666,6 +678,7 @@ function updateImageInfo(request,img){ function setupCreateImageDialog(){ dialogs_context.append('
    '); $create_image_dialog = $('#create_image_dialog',dialogs_context); + var dialog = $create_image_dialog; dialog.html(create_image_tmpl); @@ -694,12 +707,12 @@ function setupCreateImageDialog(){ default: $('#datablock_img',context).attr('disabled','disabled'); $('#path_img',context).attr('checked','checked'); - $('#img_source,#img_fstype,#img_size',context).parent().hide(); + $('#img_source,#img_fstype,#img_size,#file-uploader',context).parent().hide(); $('#img_path',context).parent().show(); } }); - $('#img_source,#img_fstype,#img_size',dialog).parent().hide(); + $('#img_source,#img_fstype,#img_size,#file-uploader',dialog).parent().hide(); $('#path_img',dialog).attr('checked','checked'); $('#img_path',dialog).parent().addClass("img_man"); @@ -708,24 +721,30 @@ function setupCreateImageDialog(){ var value = $(this).val(); switch (value){ case "path": - $('#img_source,#img_fstype,#img_size',context).parent().hide(); - $('#img_source,#img_fstype,#img_size',context).parent().removeClass("img_man"); + $('#img_source,#img_fstype,#img_size,#file-uploader',context).parent().hide(); + $('#img_source,#img_fstype,#img_size,#file-uploader',context).parent().removeClass("img_man"); $('#img_path',context).parent().show(); $('#img_path',context).parent().addClass("img_man"); break; case "source": - $('#img_path,#img_fstype,#img_size',context).parent().hide(); - $('#img_path,#img_fstype,#img_size',context).parent().removeClass("img_man"); + $('#img_path,#img_fstype,#img_size,#file-uploader',context).parent().hide(); + $('#img_path,#img_fstype,#img_size,#file-uploader',context).parent().removeClass("img_man"); $('#img_source',context).parent().show(); $('#img_source',context).parent().addClass("img_man"); break; case "datablock": - $('#img_source,#img_path',context).parent().hide(); - $('#img_source,#img_path',context).parent().removeClass("img_man"); + $('#img_source,#img_path,#file-uploader',context).parent().hide(); + $('#img_source,#img_path,#file-uploader',context).parent().removeClass("img_man"); $('#img_fstype,#img_size',context).parent().show(); $('#img_fstype,#img_size',context).parent().addClass("img_man"); break; - } + case "upload": + $('#img_path,#img_source,#img_fstype,#img_size',context).parent().hide(); + $('#img_path,#img_source,#img_fstype,#img_size',context).parent().removeClass("img_man"); + $('#file-uploader',context).parent().show(); + $('#file-uploader',context).parent().addClass("img_man"); + break; + }; }); @@ -752,9 +771,70 @@ function setupCreateImageDialog(){ } ); + $('#upload-progress',dialog).css({ + border: "1px solid #AAAAAA", + position: "relative", +// bottom: "29px", + width: "258px", +// left: "133px", + height: "15px", + display: "inline-block", + }); + $('#upload-progress div',dialog).css("border","1px solid #AAAAAA"); + + var img_obj; + + var uploader = new qq.FileUploaderBasic({ + button: $('#file-uploader',$create_image_dialog)[0], + action: 'upload', + multiple: false, + params: {}, + showMessage: function(message){ + //notifyMessage(message); + }, + onSubmit: function(id, fileName){ + uploader.setParams({ + img : JSON.stringify(img_obj), + file: fileName + }); + var pos_top = $(window).height() - 120; + var pos_left = 140; + var pb_dialog = $('
    '+ + '
    '+ + '
    ').dialog({ + draggable:true, + modal:false, + resizable:false, + buttons:{}, + width: 460, + minHeight: 50, + position: [pos_left, pos_top] + }); + + $('#upload-progress',pb_dialog).progressbar({value:0}); + }, + onProgress: function(id, fileName, loaded, total){ + $('div#pb_dialog #upload-progress').progressbar("option","value",Math.floor(loaded*100/total)); + }, + onComplete: function(id, fileName, responseJSON){ + notifyMessage("Image uploaded correctly"); + $('div#pb_dialog').dialog('destroy'); + Sunstone.runAction("Image.list"); + return false; + }, + onCancel: function(id, fileName){ + }, + }); + + var file_input = false; + uploader._button._options.onChange = function(input) { + file_input = input; return false; + }; $('#create_image_form_easy',dialog).submit(function(){ var exit = false; + var upload = false; $('.img_man',this).each(function(){ if (!$('input',this).val().length){ notifyError(tr("There are mandatory parameters missing")); @@ -805,6 +885,9 @@ function setupCreateImageDialog(){ img_json["SIZE"] = size; img_json["FSTYPE"] = fstype; break; + case "upload": + upload=true; + break; } //Time to add custom attributes @@ -815,8 +898,13 @@ function setupCreateImageDialog(){ }); - var obj = { "image" : img_json }; - Sunstone.runAction("Image.create", obj); + img_obj = { "image" : img_json }; + + if (upload){ + uploader._onInputChange(file_input); + } else { + Sunstone.runAction("Image.create", img_obj); + }; $create_image_dialog.dialog('close'); return false; @@ -831,6 +919,9 @@ function setupCreateImageDialog(){ } function popUpCreateImageDialog(){ + $('#file-uploader input',$create_image_dialog).removeAttr("style"); + $('#file-uploader input',$create_image_dialog).attr('style','margin:0;width:256px!important'); + $create_image_dialog.dialog('open'); } diff --git a/src/sunstone/sunstone-server.rb b/src/sunstone/sunstone-server.rb index a2636ed929..156c302248 100755 --- a/src/sunstone/sunstone-server.rb +++ b/src/sunstone/sunstone-server.rb @@ -308,6 +308,13 @@ delete '/:resource/:id' do @SunstoneServer.delete_resource(params[:resource], params[:id]) end +############################################################################## +# Upload image +############################################################################## +post '/upload'do + @SunstoneServer.upload(params[:img], request.env['rack.input'].path) +end + ############################################################################## # Create a new Resource ############################################################################## diff --git a/src/sunstone/views/index.erb b/src/sunstone/views/index.erb index c510722d46..85bfa4bc12 100644 --- a/src/sunstone/views/index.erb +++ b/src/sunstone/views/index.erb @@ -17,6 +17,7 @@ + From 5f984c664ba9788cae308faf7b1702f228ce2b18 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 16 Feb 2012 13:54:38 +0100 Subject: [PATCH 42/64] Feature #1067: Improve VLAN support in Sunstone --- src/sunstone/public/js/plugins/hosts-tab.js | 3 +- src/sunstone/public/js/plugins/vnets-tab.js | 138 ++++++++++++++++---- 2 files changed, 117 insertions(+), 24 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index bffa341124..d076b59573 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -85,11 +85,12 @@ var create_host_tmpl =
    \ \ \
    \
    \ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 87a153b4e9..daa3f60a3e 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -51,8 +51,25 @@ var create_vn_tmpl =
    \
    \
    \ + \ +
    \ \
    \ + \ + \ + \ +
    \ + \ +
    \
    \
    \ \ @@ -530,12 +547,20 @@ function updateVNetworkInfo(request,vn){ '+tr("Group")+'\ '+vn_info.GNAME+'\ \ + \ + '+tr("Bridge")+'\ + '+ (typeof(vn_info.BRIDGE) == "object" ? "--": vn_info.BRIDGE) +'\ + \ + \ + '+tr("VLAN")+'\ + '+ (vn_info.VLAN == "0" ? "no" : "yes") +'\ + \ \ '+tr("Physical device")+'\ '+ (typeof(vn_info.PHYDEV) == "object" ? "--": vn_info.PHYDEV) +'\ \ \ - '+tr("VNET ID")+'\ + '+tr("VLAN ID")+'\ '+ (typeof(vn_info.VLAN_ID) == "object" ? "--": vn_info.VLAN_ID) +'\ \ Permissions\ @@ -704,6 +729,36 @@ function setupCreateVNetDialog() { $('div#fixed',$create_vn_dialog).hide(); $('div#ranged',$create_vn_dialog).show(); }); + + $('#network_mode',dialog).change(function(){ + $('input,select#vlan,label[for!="network_mode"]', $(this).parent()).hide(); + $('input', $(this).parent()).val(""); + switch ($(this).val()) { + case "default": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + $('input#phydev,label[for="phydev"]',$create_vn_dialog).show(); + break; + case "802.1Q": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + $('input#phydev,label[for="phydev"]',$create_vn_dialog).show(); + $('select#vlan,label[for="vlan"]',$create_vn_dialog).show(); + $('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show(); + break; + case "etables": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + break; + case "openvswitch": + case "vmware": + $('input#bridge,label[for="bridge"]',$create_vn_dialog).show(); + $('select#vlan,label[for="vlan"]',$create_vn_dialog).show(); + $('input#vlan_id,label[for="vlan_id"]',$create_vn_dialog).show(); + break; + }; + }); + + //Initialize shown options + $('#network_mode',dialog).trigger("change"); + $('button',dialog).button(); @@ -786,12 +841,60 @@ function setupCreateVNetDialog() { notifyError(tr("Virtual Network name missing!")); return false; } - var bridge = $('#bridge',this).val(); - var type = $('input:checked',this).val(); + var network_json = {"name" : name}; + + var network_mode = $('select#network_mode',this).val(); + var bridge = $('#bridge',this).val(); + var phydev = $('#phydev',this).val(); + var vlan = $('#vlan',this).val(); + var vlan_id = $('#vlan_id',this).val(); + switch (network_mode) { + case "default": + if (!bridge && !phydev){ + notifyError("Bridge or physical device must be specified"); + return false; + }; + if (bridge) network_json['bridge']=bridge; + if (phydev) network_json['phydev']=phydev; + break; + case "802.1Q": + if (!phydev){ + notifyError("Physical device must be specified"); + return false; + }; + network_json['phydev']=phydev; + if (bridge) network_json['bridge']=bridge; + if (vlan_id) { + network_json['vlan']=vlan; + network_json['vlan_id']=vlan_id; + }; + break; + case "etables": + if (!bridge){ + notifyError("Bridge must be specified"); + return false; + }; + network_json['bridge']=bridge; + break; + case "openvswitch": + case "vmware": + if (!bridge){ + notifyError("Bridge must be specified"); + return false; + }; + network_json['bridge']=bridge; + if (vlan_id) { + network_json['vlan']=vlan; + network_json['vlan_id']=vlan_id; + }; + break; + }; + + var type = $('input:checked',this).val(); + network_json['type']=type; //TODO: Name and bridge provided?! - var network_json = null; if (type == "fixed") { var leases = $('#leases option', this); var leases_obj=[]; @@ -807,12 +910,7 @@ function setupCreateVNetDialog() { }); //and construct the final data for the request - network_json = { - "vnet" : { - "type" : "FIXED", - "leases" : leases_obj, - "bridge" : bridge, - "name" : name }}; + network_json["leases"] = leases_obj; } else { //type ranged @@ -827,25 +925,17 @@ function setupCreateVNetDialog() { return false; }; - //we form the object for the request - network_json = { - "vnet" : { - "type" : "RANGED", - "bridge" : bridge, - "name" : name } - }; - if (network_addr.length) - network_json["vnet"]["network_address"]=network_addr; + network_json["network_address"]=network_addr; if (network_mask.length) - network_json["vnet"]["network_mask"]=network_mask; + network_json["network_mask"]=network_mask; if (custom){ if (ip_start.length) - network_json["vnet"]["ip_start"] = ip_start; + network_json["ip_start"] = ip_start; if (ip_end.length) - network_json["vnet"]["ip_end"] = ip_end; + network_json["ip_end"] = ip_end; }; }; @@ -853,11 +943,13 @@ function setupCreateVNetDialog() { $('#custom_var_vnet_box option',$create_vn_dialog).each(function(){ var attr_name = $(this).attr('name'); var attr_value = $(this).val(); - network_json["vnet"][attr_name] = attr_value; + network_json[attr_name] = attr_value; }); //Create the VNetwork. + network_json = {"vnet" : network_json}; + Sunstone.runAction("Network.create",network_json); $create_vn_dialog.dialog('close'); return false; From a6067a8801bd5358051372831097f29096745998 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 28 Feb 2012 14:03:08 +0100 Subject: [PATCH 43/64] SelfService: take advantange of verbose parameter when listing pools. Concretely, the Compute pool. No need to request the state for every single VM now. --- src/cloud/occi/lib/ui/public/js/occi.js | 2 +- .../occi/lib/ui/public/js/plugins/compute.js | 37 ++++++------------- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/js/occi.js b/src/cloud/occi/lib/ui/public/js/occi.js index a818fe8008..a841b00ded 100644 --- a/src/cloud/occi/lib/ui/public/js/occi.js +++ b/src/cloud/occi/lib/ui/public/js/occi.js @@ -189,7 +189,7 @@ var OCCI = { $.ajax({ url: resource.toLowerCase(), type: "GET", - data: {timeout: timeout}, + data: {timeout: timeout, verbose: true}, dataType: "xml ONEjson", success: function(response){ var res = {}; diff --git a/src/cloud/occi/lib/ui/public/js/plugins/compute.js b/src/cloud/occi/lib/ui/public/js/plugins/compute.js index 5613a1b3a2..99402b25a0 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -153,13 +153,6 @@ var vm_actions = { error: onError }, - "VM.showstate" : { - type: "single", - call: OCCI.VM.show, - callback: updateVMStateCB, - error: onError - }, - "VM.refresh" : { type: "custom", call : function (){ @@ -178,7 +171,7 @@ var vm_actions = { "VM.suspend" : { type: "multiple", call: OCCI.VM.suspend, - callback: updateVMStateCB, + callback: updateVMachineElement, elements: vmElements, error: onError, notify: true @@ -187,7 +180,7 @@ var vm_actions = { "VM.resume" : { type: "multiple", call: OCCI.VM.resume, - callback: updateVMStateCB, + callback: updateVMachineElement, elements: vmElements, error: onError, notify: true @@ -196,7 +189,7 @@ var vm_actions = { "VM.stop" : { type: "multiple", call: OCCI.VM.stop, - callback: updateVMStateCB, + callback: updateVMachineElement, elements: vmElements, error: onError, notify: true @@ -214,7 +207,7 @@ var vm_actions = { "VM.shutdown" : { type: "multiple", call: OCCI.VM.shutdown, - callback: updateVMStateCB, + callback: updateVMachineElement, elements: vmElements, error: onError, notify: true @@ -223,7 +216,7 @@ var vm_actions = { "VM.cancel" : { type: "multiple", call: OCCI.VM.cancel, - callback: updateVMStateCB, + callback: updateVMachineElement, elements: vmElements, error: onError, notify: true @@ -240,7 +233,7 @@ var vm_actions = { "VM.saveas" : { type: "single", call: OCCI.VM.saveas, - callback: updateVMStateCB, + callback: updateVMachineElement, error:onError }, @@ -259,7 +252,7 @@ var vm_actions = { }; var options = ""; for (var i = 0; i'+type+''; }; $('#dialog select#instance_type').html(options); @@ -423,7 +416,7 @@ function vMachineElementArray(vm_json){ return [ '', id, - name + VMStateBulletStr(vm_json) + name ]; } @@ -473,16 +466,15 @@ function updateVMachinesView(request, vmachine_list){ $.each(vmachine_list,function(){ el_array = vMachineElementArray(this); vmachine_list_array.push(el_array); - Sunstone.runAction("VM.showstate",el_array[1]); }); updateView(vmachine_list_array,dataTable_vMachines); updateDashboard("vms",vmachine_list); }; -function updateVMStateCB(request,vm){ +function VMStateBulletStr(vm){ var vm_state = vm.COMPUTE.STATE; - var state_html = vm_state; + var state_html = ""; switch (vm_state) { case "INIT": case "PENDING": @@ -499,13 +491,8 @@ function updateVMStateCB(request,vm){ state_html = ''+vm_state+''; break; }; - - var tag = 'input#vm_'+vm.COMPUTE.ID; - var array = vMachineElementArray(vm); - array[2] = state_html + array[2]; - updateSingleElement(array,dataTable_vMachines,tag); -}; - + return state_html; +} // Refreshes the information panel for a VM function updateVMInfo(request,vm){ From 443d7aa00c6ec2bacb4678e3d2b762a96b4b0fdd Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 28 Feb 2012 14:46:35 +0100 Subject: [PATCH 44/64] Bug #1146: Prevent users from creating a VDC when no zones have been defined. --- src/ozones/Server/public/js/plugins/vdcs-tab.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index 2077aa5e2e..d03b75c7f8 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -516,6 +516,10 @@ function setupCreateVDCDialog(){ function openCreateVDCDialog(){ var dialog = $('div#create_vdc_dialog') + if (!zones_select){ + notifyError(tr("No zones defined: You need to create at least 1 zone before creating an VDC")); + return false; + }; $('select#zoneid',dialog).html(zones_select); $('select#zoneid',dialog).trigger("change"); $('#vdc_available_hosts_list',dialog).empty(); From 9279848a50126863cc7eb4d27f554291b9744cd9 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 28 Feb 2012 16:21:01 +0100 Subject: [PATCH 45/64] Feature #1147: Improve login in Sunstone Error messages are better explained. More cases are handled (for example when server is not running). Error box looks nicer and repops up when error happens again. Ajax loader gif has been added next to login button and appears when login is being performed. --- src/sunstone/public/css/login.css | 13 ++++++++++--- src/sunstone/public/js/login.js | 17 +++++++++++++---- src/sunstone/templates/login.html | 8 +++----- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/sunstone/public/css/login.css b/src/sunstone/public/css/login.css index 9c92aa9279..d275f49a57 100644 --- a/src/sunstone/public/css/login.css +++ b/src/sunstone/public/css/login.css @@ -134,10 +134,17 @@ div#login input#login_btn:hover { .error_message { display: none; position: relative; + width:400px; + margin-left: auto; + margin-right: auto; top: 80px; - font-family: Arial, Helvetica, sans-serif; - color:red; - font-size:1.6em; + font-size:1.0em; +} + +#login_spinner { + left: 44px; + position: relative; + top: 2px; } #label_remember { diff --git a/src/sunstone/public/js/login.js b/src/sunstone/public/js/login.js index 953f46aa1f..6b460d35c0 100644 --- a/src/sunstone/public/js/login.js +++ b/src/sunstone/public/js/login.js @@ -24,14 +24,19 @@ function auth_error(req, error){ switch (status){ case 401: - $("#one_error").hide(); - $("#auth_error").fadeIn("slow"); + $("#error_box").text("Invalid username or password"); break; case 500: - $("#auth_error").hide(); - $("#one_error").fadeIn("slow"); + $("#error_box").text("OpenNebula is not running or there was a server exception. Please check the server logs."); break; + case 0: + $("#error_box").text("No answer from server. Is it running?"); + break; + default: + $("#error_box").text("Unexpected error. Status "+status+". Check the server logs."); }; + $("#error_box").fadeIn("slow"); + $("#login_spinner").hide(); } function authenticate(){ @@ -39,6 +44,9 @@ function authenticate(){ var password = $("#password").val(); var remember = $("#check_remember").is(":checked"); + $("#error_box").fadeOut("slow"); + $("#login_spinner").show(); + OpenNebula.Auth.login({ data: {username: username , password: password} , remember: remember @@ -61,4 +69,5 @@ $(document).ready(function(){ }; $("input#username.box").focus(); + $("#login_spinner").hide(); }); diff --git a/src/sunstone/templates/login.html b/src/sunstone/templates/login.html index c942f3184f..1dc5352d14 100644 --- a/src/sunstone/templates/login.html +++ b/src/sunstone/templates/login.html @@ -3,6 +3,7 @@ OpenNebula Sunstone Login + @@ -25,11 +26,7 @@
    -
    - Invalid username or password -
    -
    - OpenNebula is not running +
    @@ -43,6 +40,7 @@ + retrieving
    From c1e8b55b1a19a92813a086d57ed6a0747e19c2c1 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 28 Feb 2012 16:23:22 +0100 Subject: [PATCH 46/64] Feature #1147: Improve login in oZones Error messages are better explained. More cases are handled (for example when server is not running). Error box looks nicer and repops up when error happens again. Ajax loader gif has been added next to login button and appears when login is being performed. --- src/ozones/Server/public/css/login.css | 13 +++++++++--- src/ozones/Server/public/js/login.js | 28 +++++++++++++++++--------- src/ozones/Server/templates/login.html | 9 +++------ 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/ozones/Server/public/css/login.css b/src/ozones/Server/public/css/login.css index 1ea3b09872..217c8c12ca 100644 --- a/src/ozones/Server/public/css/login.css +++ b/src/ozones/Server/public/css/login.css @@ -133,12 +133,19 @@ div#login input#login_btn:hover { } .error_message { + width: 400px; + margin-left: auto; + margin-right: auto; display: none; position: relative; top: 80px; - font-family: Arial, Helvetica, sans-serif; - color:red; - font-size:1.6em; + font-size:1.0em; +} + +#login_spinner { + left: 44px; + position: relative; + top: 2px; } #label_remember { diff --git a/src/ozones/Server/public/js/login.js b/src/ozones/Server/public/js/login.js index 70b26a3011..1ddc1ecd61 100644 --- a/src/ozones/Server/public/js/login.js +++ b/src/ozones/Server/public/js/login.js @@ -23,15 +23,21 @@ function auth_error(req, error){ var status = error.error.http_status; switch (status){ - case 401: - $("#one_error").hide(); - $("#auth_error").fadeIn("slow"); - break; - case 500: - $("#auth_error").hide(); - $("#one_error").fadeIn("slow"); - break; - } + case 401: + $("#error_box").text("Invalid username or password"); + break; + case 500: + $("#error_box").text("OpenNebula is not running or there was a server exception. Please check the server logs."); + break; + case 0: + $("#error_box").text("No answer from server. Is it running?"); + break; + default: + $("#error_box").text("Unexpected error. Status "+status+". Check the server logs."); + + }; + $("#error_box").fadeIn("slow"); + $("#login_spinner").hide(); } function authenticate(){ @@ -39,6 +45,9 @@ function authenticate(){ var password = $("#password").val(); var remember = $("#check_remember").is(":checked"); + $("#error_box").fadeOut("slow"); + $("#login_spinner").show(); + oZones.Auth.login({ data: {username: username , password: password} , remember: remember @@ -61,4 +70,5 @@ $(document).ready(function(){ }; $("input#username.box").focus(); + $("#login_spinner").hide(); }); diff --git a/src/ozones/Server/templates/login.html b/src/ozones/Server/templates/login.html index 6038b56e55..d1001aaaa4 100644 --- a/src/ozones/Server/templates/login.html +++ b/src/ozones/Server/templates/login.html @@ -3,7 +3,7 @@ OpenNebula oZones Login - + @@ -24,11 +24,7 @@
    -
    - Invalid username or password -
    -
    - OpenNebula is not running +
    @@ -42,6 +38,7 @@ + retrieving
    From 5710fda8021b31c97b5285547941a6dc03231c19 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 28 Feb 2012 16:24:47 +0100 Subject: [PATCH 47/64] Feature #1147: Improve login in SelfService Error messages are better explained. More cases are handled (for example when server is not running). Error box looks nicer and repops up when error happens again. Ajax loader gif has been added next to login button and appears when login is being performed. --- src/cloud/occi/lib/ui/public/css/login.css | 13 ++++++++++--- src/cloud/occi/lib/ui/public/js/login.js | 18 ++++++++++++++---- src/cloud/occi/lib/ui/templates/login.html | 10 +++------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/cloud/occi/lib/ui/public/css/login.css b/src/cloud/occi/lib/ui/public/css/login.css index 2fdd890a84..b58bacd20f 100644 --- a/src/cloud/occi/lib/ui/public/css/login.css +++ b/src/cloud/occi/lib/ui/public/css/login.css @@ -132,12 +132,19 @@ div#login input#login_btn:hover { } .error_message { + width: 400px; + margin-left: auto; + margin-right: auto; display: none; position: relative; top: 80px; - font-family: Arial, Helvetica, sans-serif; - color:red; - font-size:1.6em; + font-size:1.0em; +} + +#login_spinner { + left: 44px; + position: relative; + top: 2px; } #label_remember { diff --git a/src/cloud/occi/lib/ui/public/js/login.js b/src/cloud/occi/lib/ui/public/js/login.js index 721200f945..363fb781fd 100644 --- a/src/cloud/occi/lib/ui/public/js/login.js +++ b/src/cloud/occi/lib/ui/public/js/login.js @@ -24,14 +24,20 @@ function auth_error(req, error){ switch (status){ case 401: - $("#one_error").hide(); - $("#auth_error").fadeIn("slow"); + $("#error_box").text("Invalid username or password"); break; case 500: - $("#auth_error").hide(); - $("#one_error").fadeIn("slow"); + $("#error_box").text("OpenNebula is not running or there was a server exception. Please check the server logs."); break; + case 0: + $("#error_box").text("No answer from server. Is it running?"); + break; + default: + $("#error_box").text("Unexpected error. Status "+status+". Check the server logs."); + }; + $("#error_box").fadeIn("slow"); + $("#login_spinner").hide(); } function authenticate(){ @@ -40,6 +46,9 @@ function authenticate(){ password = Crypto.SHA1(password); var remember = $("#check_remember").is(":checked"); + $("#error_box").fadeOut("slow"); + $("#login_spinner").show(); + var obj = { data: {username: username, password: password}, remember: remember, @@ -70,4 +79,5 @@ $(document).ready(function(){ }; $("input#username.box").focus(); + $("#login_spinner").hide(); }); diff --git a/src/cloud/occi/lib/ui/templates/login.html b/src/cloud/occi/lib/ui/templates/login.html index 82b80c0785..8bf6d0c005 100644 --- a/src/cloud/occi/lib/ui/templates/login.html +++ b/src/cloud/occi/lib/ui/templates/login.html @@ -3,7 +3,7 @@ OpenNebula Self-Service Login - + @@ -28,11 +28,7 @@
    -
    - Invalid username or password -
    -
    - OpenNebula is not running +
    @@ -46,7 +42,7 @@ - + retrieving
    From 519b7f263b5cb4b399b67cb9259d9e8fff2e84c6 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 29 Feb 2012 11:09:14 +0100 Subject: [PATCH 48/64] Sunstone: small improvements to passwd operations Inform user that password change was successful. Empty the new password box when dialog is re-opened. --- src/sunstone/public/js/plugins/users-tab.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index a9d35c164f..19d48435e1 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -131,9 +131,11 @@ var user_actions = { "User.passwd" : { type: "multiple", call: OpenNebula.User.passwd, - //nocallback + callback: function(req,res){ + notifyMessage(tr("Change password successful")); + }, elements: userElements, - error: onError + error: onError, }, "User.chgrp" : { type: "multiple", @@ -492,6 +494,7 @@ function popUpCreateUserDialog(){ function popUpUpdatePasswordDialog(){ + $('#new_password',$update_pw_dialog).val(""); $update_pw_dialog.dialog('open'); } From cd3978ea9cd7e15eda082e0b2521c18475f5d79e Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 29 Feb 2012 14:33:59 +0100 Subject: [PATCH 49/64] Feature #938: Update zona unit tests They now work with latest master status. Pending: add new tests. --- src/ozones/test/etc/oned.conf.a | 57 +++++++++++++ src/ozones/test/etc/oned.conf.b | 57 +++++++++---- src/ozones/test/spec/VDCManagement_spec.rb | 95 ++++++++++++---------- src/ozones/test/templates/vdcC.template | 2 +- src/ozones/test/templates/zoneA.template | 4 +- src/ozones/test/templates/zoneB.template | 2 +- src/ozones/test/test.sh | 9 +- 7 files changed, 155 insertions(+), 71 deletions(-) create mode 100644 src/ozones/test/etc/oned.conf.a diff --git a/src/ozones/test/etc/oned.conf.a b/src/ozones/test/etc/oned.conf.a new file mode 100644 index 0000000000..4b63ff1534 --- /dev/null +++ b/src/ozones/test/etc/oned.conf.a @@ -0,0 +1,57 @@ +HOST_MONITORING_INTERVAL = 600 +#HOST_PER_INTERVAL = 15 + +VM_POLLING_INTERVAL = 600 +#VM_PER_INTERVAL = 5 + +#VM_DIR=/srv/cloud/one/var + +SCRIPTS_REMOTE_DIR=/var/tmp/one + +PORT = 2666 + +DB = [ backend = "sqlite" ] + +VNC_BASE_PORT = 5900 + +DEBUG_LEVEL = 3 + +NETWORK_SIZE = 254 + +MAC_PREFIX = "02:00" + +DEFAULT_IMAGE_TYPE = "OS" +DEFAULT_DEVICE_PREFIX = "hd" + + +IM_MAD = [ name="im_dummy", executable="one_im_dummy"] + +VM_MAD = [ name="vmm_dummy", executable="one_vmm_dummy", type="xml" ] + +TM_MAD = [ + name = "tm_dummy", + executable = "one_tm", + arguments = "tm_dummy/tm_dummy.conf" ] + +IMAGE_MAD = [ + executable = "one_image", + arguments = "fs -t 15" ] + +HM_MAD = [ + executable = "one_hm" ] + +AUTH_MAD = [ + executable = "one_auth_mad", + arguments = "--authn ssh,x509,ldap,server_cipher,server_x509" +# arguments = "--authz quota --authn ssh,x509,ldap,server_cipher,server_x509" +] + +SESSION_EXPIRATION_TIME = 900 + +VM_RESTRICTED_ATTR = "CONTEXT/FILES" +VM_RESTRICTED_ATTR = "DISK/SOURCE" +VM_RESTRICTED_ATTR = "NIC/MAC" +VM_RESTRICTED_ATTR = "NIC/VLAN_ID" +VM_RESTRICTED_ATTR = "RANK" + +IMAGE_RESTRICTED_ATTR = "SOURCE" diff --git a/src/ozones/test/etc/oned.conf.b b/src/ozones/test/etc/oned.conf.b index c7f90b798d..589cf164ba 100644 --- a/src/ozones/test/etc/oned.conf.b +++ b/src/ozones/test/etc/oned.conf.b @@ -1,30 +1,57 @@ -#******************************************************************************* -# OpenNebula Configuration file -#******************************************************************************* - -# General - HOST_MONITORING_INTERVAL = 600 +#HOST_PER_INTERVAL = 15 + VM_POLLING_INTERVAL = 600 +#VM_PER_INTERVAL = 5 + +#VM_DIR=/srv/cloud/one/var + SCRIPTS_REMOTE_DIR=/var/tmp/one -PORT=2637 + +PORT = 2667 + DB = [ backend = "sqlite" ] + VNC_BASE_PORT = 5900 -DEBUG_LEVEL=3 + +DEBUG_LEVEL = 3 + NETWORK_SIZE = 254 + MAC_PREFIX = "02:00" + DEFAULT_IMAGE_TYPE = "OS" DEFAULT_DEVICE_PREFIX = "hd" -# Dummy IM_MAD = [ name="im_dummy", executable="one_im_dummy"] -VM_MAD = [ name="vmm_dummy",executable="one_vmm_dummy", type="xml" ] -TM_MAD = [ name="tm_dummy", executable="one_tm", arguments ="tm_dummy/tm_dummy.conf" ] -# Image -IMAGE_MAD = [ executable = "one_image", arguments = "fs -t 15" ] +VM_MAD = [ name="vmm_dummy", executable="one_vmm_dummy", type="xml" ] -# Hook -HM_MAD = [ executable = "one_hm" ] +TM_MAD = [ + name = "tm_dummy", + executable = "one_tm", + arguments = "tm_dummy/tm_dummy.conf" ] +IMAGE_MAD = [ + executable = "one_image", + arguments = "fs -t 15" ] + +HM_MAD = [ + executable = "one_hm" ] + +AUTH_MAD = [ + executable = "one_auth_mad", + arguments = "--authn ssh,x509,ldap,server_cipher,server_x509" +# arguments = "--authz quota --authn ssh,x509,ldap,server_cipher,server_x509" +] + +SESSION_EXPIRATION_TIME = 900 + +VM_RESTRICTED_ATTR = "CONTEXT/FILES" +VM_RESTRICTED_ATTR = "DISK/SOURCE" +VM_RESTRICTED_ATTR = "NIC/MAC" +VM_RESTRICTED_ATTR = "NIC/VLAN_ID" +VM_RESTRICTED_ATTR = "RANK" + +IMAGE_RESTRICTED_ATTR = "SOURCE" diff --git a/src/ozones/test/spec/VDCManagement_spec.rb b/src/ozones/test/spec/VDCManagement_spec.rb index 03b8c32c82..832fd8a37d 100644 --- a/src/ozones/test/spec/VDCManagement_spec.rb +++ b/src/ozones/test/spec/VDCManagement_spec.rb @@ -33,85 +33,90 @@ module OZones describe "oZones server regarding VDCs" do before(:all) do - @zonehelper = + @zonehelper = ZonesHelper.new("zone", "ozonesadmin","ozonespassword") - @vdchelper = - VDCHelper.new("vdc", "ozonesadmin","ozonespassword") - + @vdchelper = + VDCHelper.new("vdc", "ozonesadmin","ozonespassword") + @clientA = OpenNebula::Client.new(File.read( - File.dirname(__FILE__)+"/../etc/one_auth_a"), - "http://localhost:2636/RPC2") - + File.dirname(__FILE__)+"/../etc/one_auth_a"), + "http://localhost:2666/RPC2") + @clientB = OpenNebula::Client.new(File.read( - File.dirname(__FILE__)+"/../etc/one_auth_b"), - "http://localhost:2637/RPC2") - + File.dirname(__FILE__)+"/../etc/one_auth_b"), + "http://localhost:2667/RPC2") + hostA=OpenNebula::Host.new(OpenNebula::Host.build_xml, @clientA) - hostA.allocate("hostA1","im_dummy","vmm_dummy","tm_dummy") - hostA.allocate("hostA2","im_dummy","vmm_dummy","tm_dummy") - hostA.allocate("hostA3","im_dummy","vmm_dummy","tm_dummy") - hostA.allocate("hostA4","im_dummy","vmm_dummy","tm_dummy") - + hostA.allocate("hostA1","im_dummy","vmm_dummy","tm_dummy","dummy") + hostA.allocate("hostA2","im_dummy","vmm_dummy","tm_dummy","dummy") + hostA.allocate("hostA3","im_dummy","vmm_dummy","tm_dummy","dummy") + hostA.allocate("hostA4","im_dummy","vmm_dummy","tm_dummy","dummy") + hostB=OpenNebula::Host.new(OpenNebula::Host.build_xml, @clientB) - hostB.allocate("hostB1","im_dummy","vmm_dummy","tm_dummy") - hostB.allocate("hostB2","im_dummy","vmm_dummy","tm_dummy") - hostB.allocate("hostB3","im_dummy","vmm_dummy","tm_dummy") + hostB.allocate("hostB1","im_dummy","vmm_dummy","tm_dummy","dummy") + hostB.allocate("hostB2","im_dummy","vmm_dummy","tm_dummy","dummy") + hostB.allocate("hostB3","im_dummy","vmm_dummy","tm_dummy","dummy") end - + it "should be able to create a couple of zones" do @zonehelper.create_resource(File.dirname(__FILE__)+ "/../templates/zoneA.template")[0].should eql(0) @zonehelper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneB.template")[0].should eql(0) - end - + "/../templates/zoneB.template")[0].should eql(0) + end + it "should be able to create one vdc with the apropiate ONE resources" do @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcA.template")[0].should eql(0) - + "/../templates/vdcA.template", + {:force => false})[0].should eql(0) + upool = OpenNebula::UserPool.new(@clientA) upool.info userExist=false - upool.each{|user| + upool.each{|user| if user['NAME'] == "vdcadminA" userExist=true end } - + userExist.should eql(true) - + gpool = OpenNebula::GroupPool.new(@clientA) gpool.info groupExist=false - gpool.each{|group| + gpool.each{|group| if group['NAME'] == "vdcA" groupExist=true end - } - + } + groupExist.should eql(true) - + apool = OpenNebula::AclPool.new(@clientA) apool.info # TODO check ACLs end - - it "should be able to create a couple of VDCs" do + + it "should be able to create a couple of VDCs" do @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcB.template")[0].should eql(0) + "/../templates/vdcB.template", + {:force => false})[0].should eql(0) @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcC.template")[0].should eql(0) - end - - it "should fail when creating an existing VDC" do + "/../templates/vdcC.template", + {:force => false})[0].should eql(0) + end + + it "should fail when creating an existing VDC" do @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcA.template")[0].should eql(-1) - end - - it "should fail when creating a VDC upon a non existing zone" do + "/../templates/vdcA.template", + {:force => false})[0].should eql(-1) + end + + it "should fail when creating a VDC upon a non existing zone" do @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdc.no.zone.template")[0].should eql(-1) - end - + "/../templates/vdc.no.zone.template", + {:force => false})[0].should eql(-1) + end + end end diff --git a/src/ozones/test/templates/vdcC.template b/src/ozones/test/templates/vdcC.template index 31fbb6c4a0..47c2b9148b 100644 --- a/src/ozones/test/templates/vdcC.template +++ b/src/ozones/test/templates/vdcC.template @@ -2,4 +2,4 @@ NAME=vdcC VDCADMINNAME=vdcadminC VDCADMINPASS=vdcpassC ZONEID=1 -HOSTS=3 \ No newline at end of file +HOSTS=4 diff --git a/src/ozones/test/templates/zoneA.template b/src/ozones/test/templates/zoneA.template index 35b6adfb5f..bd92fcb475 100644 --- a/src/ozones/test/templates/zoneA.template +++ b/src/ozones/test/templates/zoneA.template @@ -1,5 +1,5 @@ NAME=zoneA ONENAME=oneadminA ONEPASS=opennebulaA -ENDPOINT=http://localhost:2636/RPC2 -SUNSENDPOINT=http://localhost:9869 \ No newline at end of file +ENDPOINT=http://localhost:2666/RPC2 +SUNSENDPOINT=http://localhost:9869 diff --git a/src/ozones/test/templates/zoneB.template b/src/ozones/test/templates/zoneB.template index 3eb7b9348b..9aa9cdda36 100644 --- a/src/ozones/test/templates/zoneB.template +++ b/src/ozones/test/templates/zoneB.template @@ -1,4 +1,4 @@ NAME=zoneB ONENAME=oneadminB ONEPASS=opennebulaB -ENDPOINT=http://localhost:2637/RPC2 \ No newline at end of file +ENDPOINT=http://localhost:2667/RPC2 diff --git a/src/ozones/test/test.sh b/src/ozones/test/test.sh index 963032dcf2..a1822faffc 100755 --- a/src/ozones/test/test.sh +++ b/src/ozones/test/test.sh @@ -35,8 +35,7 @@ for j in `ls ./spec/*_spec.rb` ; do OZONES_AUTH=$PWD/etc/ozones_auth ONE_LOCATION=$ONE_LOCATION_A oneA/bin/ozones-server start sleep 5 - - ONE_LOCATION=$ONE_LOCATION_A spec $j -f s + ONE_LOCATION=$ONE_LOCATION_A rspec $j -f s CODE=$? if [ $CODE != 0 ] ; then @@ -62,8 +61,4 @@ if (($CODE == 0)); then # Delete directories rm -rf oneA rm -rf oneB -fi - - - - +fi \ No newline at end of file From f44bb4940efaaa10486afe79c89935068b28a545 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 2 Mar 2012 13:37:02 +0100 Subject: [PATCH 50/64] Feature #1109: Add SelfService support in ozones Add self service end point when creating a zone. Show self service public link when showing VDC information. --- .../Server/public/js/plugins/vdcs-tab.js | 12 ++++++--- .../Server/public/js/plugins/zones-tab.js | 27 ++++++++++++++++--- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index d03b75c7f8..4a4f8cbb1f 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -282,12 +282,14 @@ function updateVDCInfo(req,vdc_json){ var zone_host = ""; var zone_port = ""; var sun_link = ""; + var self_link = ""; var zone_match = zone_endpoint.match(/^https?:\/\/([\w.-]+):(\d+)\/([\W\w]+)$/); if (zone_match){ zone_host = zone_match[1]; zone_port = zone_match[2]; sun_link = "http://" + zone_host +"/sunstone_"+ vdc.NAME+"/"; + self_link = "http://" + zone_host +"/self_"+ vdc.NAME+"/"; }; var info_tab = { @@ -330,6 +332,10 @@ function updateVDCInfo(req,vdc_json){ Sunstone public link\ '+(sun_link.length? ''+sun_link+'' : "")+'\ \ + \ + SelfService public link\ + '+(self_link.length? ''+self_link+'' : "")+'\ + \ \ ONE_XMLPRC (to export for CLI access)\ \ @@ -501,12 +507,10 @@ function setupCreateVDCDialog(){ "ZONEID" : zoneid, "VDCADMINNAME" : vdcadminname, "VDCADMINPASS" : vdcadminpass, - "FORCE" : force + "FORCE" : force, + "HOSTS" : hosts } }; - if (hosts.length){ - vdc_json["VDC"]["HOSTS"]=hosts; - }; Sunstone.runAction("VDC.create",vdc_json); dialog.dialog('close'); diff --git a/src/ozones/Server/public/js/plugins/zones-tab.js b/src/ozones/Server/public/js/plugins/zones-tab.js index 4fbb8daeb4..d7430e75ad 100644 --- a/src/ozones/Server/public/js/plugins/zones-tab.js +++ b/src/ozones/Server/public/js/plugins/zones-tab.js @@ -53,6 +53,12 @@ var create_zone_tmpl = /\ \
    \ + \ + ://\ + :\ + /\ + \ +
    \
    \ \
    \ @@ -310,8 +316,12 @@ function updateZoneInfo(req,zone_json){ '+zone.ENDPOINT+'\ \ \ - Sunstone endpoint\ -'+ (zone.SUNSENDPOINT.length? ''+zone.SUNSENDPOINT+'' : "") +'\ + Sunstone endpoint\ + '+ (zone.SUNSENDPOINT.length? ''+zone.SUNSENDPOINT+'' : "") +'\ + \ + \ + SelfService endpoint\ + '+ (zone.SELFENDPOINT.length? ''+zone.SELFENDPOINT+'' : "") +'\ \ \ #VDCs\ @@ -557,11 +567,17 @@ function setupCreateZoneDialog(){ var endpoint_port = $('#endpoint_port',this).val(); var onename = $('#onename',this).val(); var onepass = $('#onepass',this).val(); + var se = $('#sunsendpoint',this).val(); var se_ptc = $('#sunsendpoint_ptc',this).val(); var se_port = $('#sunsendpoint_port',this).val(); var se_path = $('#sunsendpoint_path',this).val(); + var ss = $('#selfsendpoint',this).val(); + var ss_ptc = $('#selfsendpoint_ptc',this).val(); + var ss_port = $('#selfsendpoint_port',this).val(); + var ss_path = $('#selfsendpoint_path',this).val(); + if (!name.length || !endpoint.length || !onename.length || !onepass.length){ notifyError("Please fill in all fields"); @@ -575,13 +591,18 @@ function setupCreateZoneDialog(){ se = se_ptc + "://" + se + ":" + se_port + "/" + se_path; + if (ss.length) + ss = ss_ptc + "://" + ss + ":" + ss_port + + "/" + ss_path; + var zone_json = { "ZONE": { "NAME": name, "ENDPOINT": endpoint, "ONENAME": onename, "ONEPASS": onepass, - "SUNSENDPOINT" : se + "SUNSENDPOINT" : se, + "SELFENDPOINT" : ss, } }; From e4b34a7e4e175da871b796396d054bf36ae2de7f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 5 Mar 2012 11:32:36 +0100 Subject: [PATCH 51/64] Ozones: enable raw JSON output from CLI commands --- src/ozones/Client/bin/onevdc | 5 ++- src/ozones/Client/bin/onezone | 44 ++++++++++++++-------- src/ozones/Client/lib/cli/ozones_helper.rb | 34 ++++++++++++++--- 3 files changed, 60 insertions(+), 23 deletions(-) diff --git a/src/ozones/Client/bin/onevdc b/src/ozones/Client/bin/onevdc index b584c7fb6f..1fb688a2b2 100755 --- a/src/ozones/Client/bin/onevdc +++ b/src/ozones/Client/bin/onevdc @@ -61,11 +61,12 @@ cmd=CommandParser::CmdParser.new(ARGV) do helper.create_resource(args[0], options) end - command :show, 'Show information of a particular VDC', :vdcid do + command :show, 'Show information of a particular VDC', :vdcid, + :options => OZonesHelper::JSON do helper.show_resource(args[0],options) end - command :list, 'Lists VDCs in the pool' do + command :list, 'Lists VDCs in the pool', :options => OZonesHelper::JSON do helper.list_pool(options) end diff --git a/src/ozones/Client/bin/onezone b/src/ozones/Client/bin/onezone index af922e7bcb..5eae35012e 100755 --- a/src/ozones/Client/bin/onezone +++ b/src/ozones/Client/bin/onezone @@ -71,8 +71,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do onezone show 4 host EOT - command :show, show_desc, :zoneid, [:resource, nil] do - zone=helper.show_resource(args[0],options)[1] + command :show, show_desc, :zoneid, [:resource, nil], + :options => OZonesHelper::JSON do + zone = helper.show_resource(args[0],options)[1] + + #manually print here + if options[:json] + puts zone + end + + if !args[1] then next 0 end case args[1] when "host" @@ -87,35 +95,41 @@ cmd=CommandParser::CmdParser.new(ARGV) do aux_helper = OneTemplateHelper.new when "user" aux_helper = OneUserHelper.new - else - puts "\n:!: Pool #{args[1]} doesn't exist or is not supported\n\n" - next 0 + else + puts "\n:!: Pool #{args[1]} doesn't exist or is not supported\n\n" + next 0 end - pool_hash_data = helper.get_resource_pool("zone", zone[:ID], args[1]) + pool_hash_data = helper.get_resource_pool("zone", args[0], args[1], + options) - if pool_hash_data[0] != 0 - puts "\nError retrieving information for pool #{args[1]}. Reason: " + pool_hash_data[1] + "\n\n" + if pool_hash_data[0] != 0 + puts "\nError retrieving information for pool #{args[1]}. Reason: " + pool_hash_data[1] + "\n\n" next 0 - end + end - if !pool_hash_data[1] - next 0 + if !pool_hash_data[1] + next 0 + end + + if options[:json] + puts pool_hash_data[1] + next 0 end if pool_hash_data[1].is_a?(Hash) pool_hash_data[1]=[Hash.transform_keys_to_strings(pool_hash_data[1])] - else - pool_hash_data[1].each{|hash| hash.replace(Hash.transform_keys_to_strings(hash))} + else + pool_hash_data[1].each{|hash| hash.replace(Hash.transform_keys_to_strings(hash))} end table = aux_helper.format_pool(options) - table.show(pool_hash_data[1]) + table.show(pool_hash_data[1]) 0 end - command :list, 'Lists Zones in the pool' do + command :list, 'Lists Zones in the pool', :options=>OZonesHelper::JSON do helper.list_pool(options) end diff --git a/src/ozones/Client/lib/cli/ozones_helper.rb b/src/ozones/Client/lib/cli/ozones_helper.rb index 6ce320b5e8..cf13653354 100644 --- a/src/ozones/Client/lib/cli/ozones_helper.rb +++ b/src/ozones/Client/lib/cli/ozones_helper.rb @@ -18,6 +18,15 @@ require 'zona' module OZonesHelper + #Specific ozones CLI options + + JSON={ + :name => "json", + :short => "-j", + :large => "--json", + :description => "Show the resource in JSON format" + } + class OZHelper def initialize(user=nil, pass=nil, endpoint_str=nil, timeout=nil, debug_flag=true) @@ -45,8 +54,13 @@ module OZonesHelper if Zona::is_error?(rc) [-1, rc.message] else - pool=Zona::OZonesJSON.parse_json(rc.body, kind.upcase + "_POOL") - format_pool(pool, options) + if options[:json] + [0, rc.body] + else + resource_str = kind.upcase + "_POOL" + pool=Zona::OZonesJSON.parse_json(rc.body, resource_str) + format_pool(pool, options) + end end end @@ -56,18 +70,26 @@ module OZonesHelper if Zona::is_error?(rc) [-1, rc.message] else - resource=Zona::OZonesJSON.parse_json(rc.body, kind.upcase) - format_resource(resource, options) + if options[:json] + [0, rc.body] + else + resource=Zona::OZonesJSON.parse_json(rc.body, kind.upcase) + format_resource(resource, options) + end end end - def get_resource_pool(kind, id, pool) + def get_resource_pool(kind, id, pool, options) rc = @client.get_resource_pool(kind, id, pool) if Zona::is_error?(rc) [-1, rc.message] else - [0 , Zona::OZonesJSON.parse_json(rc.body, pool.upcase+"_POOL")[pool.upcase.to_sym]] + if options[:json] + [0, rc.body] + else + [0 , Zona::OZonesJSON.parse_json(rc.body, pool.upcase+"_POOL")[pool.upcase.to_sym]] + end end end From f2e86d4b487ac4ceb20e57c35790eca10e1c1501 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 6 Mar 2012 12:17:01 +0100 Subject: [PATCH 52/64] Feature #938: Move tests from ozones/Server/test to ozones/test --- src/ozones/Server/test/Rakefile | 9 -- .../Server/test/examples/pool/vdcpool0.json | 18 --- .../test/examples/pool/vdcpool1deleted.json | 12 -- .../Server/test/examples/pool/zonepool0.json | 22 --- .../test/examples/pool/zonepool1deleted.json | 14 -- src/ozones/Server/test/examples/vdc/vdc0.json | 8 -- .../Server/test/examples/vdc/vdc0.template | 5 - .../Server/test/examples/vdc/vdc1.template | 5 - .../test/examples/vdc/vdc2nozone.template | 3 - .../Server/test/examples/zone/zone0.json | 23 --- .../Server/test/examples/zone/zone0.template | 4 - .../Server/test/examples/zone/zone1.template | 4 - src/ozones/Server/test/spec/pools_spec.rb | 133 ------------------ src/ozones/Server/test/test.sh | 46 ------ src/ozones/test/examples/pool/vdcpool0.json | 36 +++++ .../test/examples/pool/vdcpool_deleted.json | 26 ++++ src/ozones/test/examples/pool/zonepool0.json | 26 ++++ .../test/examples/pool/zonepool_deleted.json | 16 +++ src/ozones/test/examples/vdc/vdc0.json | 12 ++ src/ozones/test/examples/zone/zone0.json | 14 ++ src/ozones/test/spec/VDCManagement_spec.rb | 58 +++++--- src/ozones/test/spec/ZoneManagement_spec.rb | 81 ++++++++--- src/ozones/test/test.sh | 7 - 23 files changed, 228 insertions(+), 354 deletions(-) delete mode 100644 src/ozones/Server/test/Rakefile delete mode 100644 src/ozones/Server/test/examples/pool/vdcpool0.json delete mode 100644 src/ozones/Server/test/examples/pool/vdcpool1deleted.json delete mode 100644 src/ozones/Server/test/examples/pool/zonepool0.json delete mode 100644 src/ozones/Server/test/examples/pool/zonepool1deleted.json delete mode 100644 src/ozones/Server/test/examples/vdc/vdc0.json delete mode 100644 src/ozones/Server/test/examples/vdc/vdc0.template delete mode 100644 src/ozones/Server/test/examples/vdc/vdc1.template delete mode 100644 src/ozones/Server/test/examples/vdc/vdc2nozone.template delete mode 100644 src/ozones/Server/test/examples/zone/zone0.json delete mode 100644 src/ozones/Server/test/examples/zone/zone0.template delete mode 100644 src/ozones/Server/test/examples/zone/zone1.template delete mode 100644 src/ozones/Server/test/spec/pools_spec.rb delete mode 100755 src/ozones/Server/test/test.sh create mode 100644 src/ozones/test/examples/pool/vdcpool0.json create mode 100644 src/ozones/test/examples/pool/vdcpool_deleted.json create mode 100644 src/ozones/test/examples/pool/zonepool0.json create mode 100644 src/ozones/test/examples/pool/zonepool_deleted.json create mode 100644 src/ozones/test/examples/vdc/vdc0.json create mode 100644 src/ozones/test/examples/zone/zone0.json diff --git a/src/ozones/Server/test/Rakefile b/src/ozones/Server/test/Rakefile deleted file mode 100644 index 1cc32ded2d..0000000000 --- a/src/ozones/Server/test/Rakefile +++ /dev/null @@ -1,9 +0,0 @@ -require 'rake' -require 'spec/rake/spectask' - -desc "Run all tests with RCov" -Spec::Rake::SpecTask.new('test_with_rcov') do |t| - t.spec_files = FileList['spec/*_spec.rb'] - t.rcov = true - t.rcov_opts = ['--exclude', '/Library'] -end \ No newline at end of file diff --git a/src/ozones/Server/test/examples/pool/vdcpool0.json b/src/ozones/Server/test/examples/pool/vdcpool0.json deleted file mode 100644 index 568adf4dd9..0000000000 --- a/src/ozones/Server/test/examples/pool/vdcpool0.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "vdcpool": { - "vdc": [ - { - "hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2", - "zones_id": 1, - "name": "testvdc0", - "id": 1 - }, - { - "hosts": "testhostvdc1n0", - "zones_id": 1, - "name": "testvdc1", - "id": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/ozones/Server/test/examples/pool/vdcpool1deleted.json b/src/ozones/Server/test/examples/pool/vdcpool1deleted.json deleted file mode 100644 index 4f0d258aa9..0000000000 --- a/src/ozones/Server/test/examples/pool/vdcpool1deleted.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "vdcpool": { - "vdc": [ - { - "hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2", - "zones_id": 1, - "name": "testvdc0", - "id": 1 - } - ] - } -} \ No newline at end of file diff --git a/src/ozones/Server/test/examples/pool/zonepool0.json b/src/ozones/Server/test/examples/pool/zonepool0.json deleted file mode 100644 index 05b79f2255..0000000000 --- a/src/ozones/Server/test/examples/pool/zonepool0.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "zonepool": { - "zone": [ - { - "onename": "oneadmin", - "onepass": "opennebula", - "endpoint": "http://localhost:2633/RPC2", - "numbervdcs": 2, - "name": "testzone0", - "id": 1 - }, - { - "onename": "testname", - "onepass": "testpass", - "endpoint": "http://remoteserver:2633/RPC2", - "numbervdcs": 0, - "name": "testzone1", - "id": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/ozones/Server/test/examples/pool/zonepool1deleted.json b/src/ozones/Server/test/examples/pool/zonepool1deleted.json deleted file mode 100644 index dbd66dca25..0000000000 --- a/src/ozones/Server/test/examples/pool/zonepool1deleted.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "zonepool": { - "zone": [ - { - "onename": "oneadmin", - "onepass": "opennebula", - "endpoint": "http://localhost:2633/RPC2", - "numbervdcs": 2, - "name": "testzone0", - "id": 1 - } - ] - } -} \ No newline at end of file diff --git a/src/ozones/Server/test/examples/vdc/vdc0.json b/src/ozones/Server/test/examples/vdc/vdc0.json deleted file mode 100644 index 6deb95903d..0000000000 --- a/src/ozones/Server/test/examples/vdc/vdc0.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "vdc": { - "hosts": "5,7,9", - "zones_id": 1, - "name": "testvdc0", - "id": 1 - } -} \ No newline at end of file diff --git a/src/ozones/Server/test/examples/vdc/vdc0.template b/src/ozones/Server/test/examples/vdc/vdc0.template deleted file mode 100644 index b2e7e3d4f3..0000000000 --- a/src/ozones/Server/test/examples/vdc/vdc0.template +++ /dev/null @@ -1,5 +0,0 @@ -NAME=testvdc0 -ZONEID=1 -HOSTS=5,7,9 -VDCADMINNAME=adminname -VDCADMINPASS=adminpass diff --git a/src/ozones/Server/test/examples/vdc/vdc1.template b/src/ozones/Server/test/examples/vdc/vdc1.template deleted file mode 100644 index 4566505bbb..0000000000 --- a/src/ozones/Server/test/examples/vdc/vdc1.template +++ /dev/null @@ -1,5 +0,0 @@ -NAME=testvdc1 -HOSTS=8 -ZONEID=1 -VDCADMINNAME=othername -VDCADMINPASS=otherpass \ No newline at end of file diff --git a/src/ozones/Server/test/examples/vdc/vdc2nozone.template b/src/ozones/Server/test/examples/vdc/vdc2nozone.template deleted file mode 100644 index 946c43c46c..0000000000 --- a/src/ozones/Server/test/examples/vdc/vdc2nozone.template +++ /dev/null @@ -1,3 +0,0 @@ -NAME=testvdcnozone -HOSTS=3,7 -ZONEID=5 \ No newline at end of file diff --git a/src/ozones/Server/test/examples/zone/zone0.json b/src/ozones/Server/test/examples/zone/zone0.json deleted file mode 100644 index 3577998a60..0000000000 --- a/src/ozones/Server/test/examples/zone/zone0.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "zone": { - "onename": "oneadmin", - "onepass": "opennebula", - "endpoint": "http://localhost:2633/RPC2", - "name": "testzone0", - "id": 1, - "vdcs": [ - { - "hosts": "testhostvdc0n0,testhostvdc0n1,testhostvdc0n2", - "zones_id": 1, - "name": "testvdc0", - "id": 1 - }, - { - "hosts": "testhostvdc1n0", - "zones_id": 1, - "name": "testvdc1", - "id": 2 - } - ] - } -} \ No newline at end of file diff --git a/src/ozones/Server/test/examples/zone/zone0.template b/src/ozones/Server/test/examples/zone/zone0.template deleted file mode 100644 index acad3af06e..0000000000 --- a/src/ozones/Server/test/examples/zone/zone0.template +++ /dev/null @@ -1,4 +0,0 @@ -NAME=testzone0 -ENDPOINT=http://localhost:2633/RPC2 -ONENAME=oneadmin -ONEPASS=opennebula \ No newline at end of file diff --git a/src/ozones/Server/test/examples/zone/zone1.template b/src/ozones/Server/test/examples/zone/zone1.template deleted file mode 100644 index 4c1459667c..0000000000 --- a/src/ozones/Server/test/examples/zone/zone1.template +++ /dev/null @@ -1,4 +0,0 @@ -NAME=testzone1 -ENDPOINT=http://remoteserver:2633/RPC2 -ONENAME=testname -ONEPASS=testpass \ No newline at end of file diff --git a/src/ozones/Server/test/spec/pools_spec.rb b/src/ozones/Server/test/spec/pools_spec.rb deleted file mode 100644 index 4fd7667c7c..0000000000 --- a/src/ozones/Server/test/spec/pools_spec.rb +++ /dev/null @@ -1,133 +0,0 @@ -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - -# Load libraries -require 'rubygems' -require 'spec' -require 'json' -require File.dirname(__FILE__) + "/../../../Client/lib/OZonesClient.rb" - -EXAMPLES_PATH = File.dirname(__FILE__) + "/../examples/" - -describe 'OZones Pool' do - before(:all) do - @client_launched = true - - begin - @ozones_client = OZonesClient::Client.new("http://localhost:6121") - rescue Exception => e - @client_launched = false - end - - @client_launched.should == true - - rc = @ozones_client.post_resource( - "zone",EXAMPLES_PATH + '/zone/zone0.template') - rc.class.should_not eql(OZonesClient::Error) - - rc = @ozones_client.post_resource( - "zone",EXAMPLES_PATH + '/zone/zone1.template') - rc.class.should_not eql(OZonesClient::Error) - - rc = @ozones_client.post_resource( - "vdc",EXAMPLES_PATH + '/vdc/vdc0.template') - rc.class.should_not eql(OZonesClient::Error) - - rc = @ozones_client.post_resource( - "vdc",EXAMPLES_PATH + '/vdc/vdc1.template') - rc.class.should_not eql(OZonesClient::Error) - - end - - it "should be able to retrieve the zone pool" do - zonepool = @ozones_client.get_pool("zone") - zonepool.class.should eql(Net::HTTPOK) - zonepool.body.should eql( - File.read(EXAMPLES_PATH+'/pool/zonepool0.json')) - end - - it "should be able to retrieve the vdc pool" do - vdcpool = @ozones_client.get_pool("vdc") - vdcpool.class.should eql(Net::HTTPOK) - vdcpool.body.should eql( - File.read(EXAMPLES_PATH+'/pool/vdcpool0.json')) - end - - it "should be able to retrieve a particular zone" do - zone0 = @ozones_client.get_resource("zone",1) - zone0.class.should eql(Net::HTTPOK) - zone0.body.should eql( - File.read(EXAMPLES_PATH+'/zone/zone0.json')) - end - - it "should be able to retrieve a particular vdc" do - vdc0 = @ozones_client.get_resource("vdc",1) - vdc0.class.should eql(Net::HTTPOK) - vdc0.body.should eql( - File.read(EXAMPLES_PATH+'/vdc/vdc0.json')) - end - - it "should fail on zone recreation (with the same name)" do - rc = @ozones_client.post_resource( - "zone",EXAMPLES_PATH + '/zone/zone0.template') - rc.class.should eql(OZonesClient::Error) - end - - it "should fail on vdc recreation (with the same name)" do - rc = @ozones_client.post_resource( - "vdc",EXAMPLES_PATH + '/vdc/vdc0.template') - rc.class.should eql(OZonesClient::Error) - end - - it "should fail on vdc creation with no existing zone" do - rc = @ozones_client.post_resource( - "vdc",EXAMPLES_PATH + - '/vdc/vdc2nozone.template') - rc.class.should eql(OZonesClient::Error) - end - - it "should allow deleting a zone" do - rc = @ozones_client.delete_resource("zone",2) - rc.class.should eql(Net::HTTPOK) - # Zone pool shouldn't account for the deleted zone - zonepool = @ozones_client.get_pool("zone") - zonepool.class.should eql(Net::HTTPOK) - zonepool.body.should eql( - File.read(EXAMPLES_PATH+ - '/pool/zonepool1deleted.json')) - end - - it "should allow deleting a vdc" do - rc = @ozones_client.delete_resource("vdc",2) - rc.class.should eql(Net::HTTPOK) - # Zone pool shouldn't account for the deleted zone - vdcpool = @ozones_client.get_pool("vdc") - vdcpool.class.should eql(Net::HTTPOK) - vdcpool.body.should eql( - File.read(EXAMPLES_PATH+ - '/pool/vdcpool1deleted.json')) - end - - it "should fail on non existing zone deletion" do - rc = @ozones_client.delete_resource("zone",5) - rc.class.should eql(OZonesClient::Error) - end - - it "should fail on non existing vdc deletion" do - rc = @ozones_client.delete_resource("vdc",5) - rc.class.should eql(OZonesClient::Error) - end -end diff --git a/src/ozones/Server/test/test.sh b/src/ozones/Server/test/test.sh deleted file mode 100755 index 98fa138442..0000000000 --- a/src/ozones/Server/test/test.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -# -------------------------------------------------------------------------- # -# Copyright 2002-2012, OpenNebula Project Leads (OpenNebula.org) # -# # -# Licensed under the Apache License, Version 2.0 (the "License"); you may # -# not use this file except in compliance with the License. You may obtain # -# a copy of the License at # -# # -# http://www.apache.org/licenses/LICENSE-2.0 # -# # -# Unless required by applicable law or agreed to in writing, software # -# distributed under the License is distributed on an "AS IS" BASIS, # -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # -# See the License for the specific language governing permissions and # -# limitations under the License. # -#--------------------------------------------------------------------------- # - - -VAR_LOCATION="$PWD/var" -OZONES_LOCATION="$PWD/../" - -mkdir -p $VAR_LOCATION - -if [ "$(ls -A $VAR_LOCATION)" ]; then - echo "$VAR_LOCATION is not empty." - exit -1 -fi - -rm -rf coverage_server - -rcov --exclude /Library --exclude /Users/tinova/.gem -o coverage_server `which rackup` -- $OZONES_LOCATION/config.ru -s thin -p 6121 -o localhost &> server.log & -RCOVPID=$! -sleep 5 - -rake test_with_rcov -CODE=$? - -kill $RCOVPID -sleep 2s; - -if [ $CODE != 0 ] ; then - exit 1 -fi - -find $VAR_LOCATION -mindepth 1 -delete diff --git a/src/ozones/test/examples/pool/vdcpool0.json b/src/ozones/test/examples/pool/vdcpool0.json new file mode 100644 index 0000000000..1401a09b5b --- /dev/null +++ b/src/ozones/test/examples/pool/vdcpool0.json @@ -0,0 +1,36 @@ +{ + "VDC_POOL": { + "VDC": [ + { + "ID": 1, + "ACLS": "2,3,4,5,6,7", + "HOSTS": "1,2,3", + "NAME": "vdcA", + "ZONES_ID": 1, + "GROUP_ID": 100, + "VDCADMINNAME": "vdcadminA", + "VDCADMIN_ID": 2 + }, + { + "ID": 2, + "ACLS": "2,3,4,5", + "HOSTS": "1", + "NAME": "vdcB", + "ZONES_ID": 2, + "GROUP_ID": 100, + "VDCADMINNAME": "vdcadminB", + "VDCADMIN_ID": 2 + }, + { + "ID": 3, + "ACLS": "8,9,10,11", + "HOSTS": "4", + "NAME": "vdcC", + "ZONES_ID": 1, + "GROUP_ID": 101, + "VDCADMINNAME": "vdcadminC", + "VDCADMIN_ID": 3 + } + ] + } +} \ No newline at end of file diff --git a/src/ozones/test/examples/pool/vdcpool_deleted.json b/src/ozones/test/examples/pool/vdcpool_deleted.json new file mode 100644 index 0000000000..bd6fd87e84 --- /dev/null +++ b/src/ozones/test/examples/pool/vdcpool_deleted.json @@ -0,0 +1,26 @@ +{ + "VDC_POOL": { + "VDC": [ + { + "ID": 1, + "ACLS": "2,3,4,5,6,7", + "HOSTS": "1,2,3", + "NAME": "vdcA", + "ZONES_ID": 1, + "GROUP_ID": 100, + "VDCADMINNAME": "vdcadminA", + "VDCADMIN_ID": 2 + }, + { + "ID": 2, + "ACLS": "2,3,4,5", + "HOSTS": "1", + "NAME": "vdcB", + "ZONES_ID": 2, + "GROUP_ID": 100, + "VDCADMINNAME": "vdcadminB", + "VDCADMIN_ID": 2 + } + ] + } +} \ No newline at end of file diff --git a/src/ozones/test/examples/pool/zonepool0.json b/src/ozones/test/examples/pool/zonepool0.json new file mode 100644 index 0000000000..1eaf1751fa --- /dev/null +++ b/src/ozones/test/examples/pool/zonepool0.json @@ -0,0 +1,26 @@ +{ + "ZONE_POOL": { + "ZONE": [ + { + "ID": 1, + "ENDPOINT": "http://localhost:2666/RPC2", + "NUMBERVDCS": 0, + "SUNSENDPOINT": "http://localhost:9869", + "NAME": "zoneA", + "SELFENDPOINT": null, + "ONENAME": "oneadminA", + "ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==" + }, + { + "ID": 2, + "ENDPOINT": "http://localhost:2667/RPC2", + "NUMBERVDCS": 0, + "SUNSENDPOINT": null, + "NAME": "zoneB", + "SELFENDPOINT": null, + "ONENAME": "oneadminB", + "ONEPASS": "8Si8vlo2P3qn5/SNxkMkDg==" + } + ] + } +} \ No newline at end of file diff --git a/src/ozones/test/examples/pool/zonepool_deleted.json b/src/ozones/test/examples/pool/zonepool_deleted.json new file mode 100644 index 0000000000..6ec991ee16 --- /dev/null +++ b/src/ozones/test/examples/pool/zonepool_deleted.json @@ -0,0 +1,16 @@ +{ + "ZONE_POOL": { + "ZONE": [ + { + "ID": 1, + "ENDPOINT": "http://localhost:2666/RPC2", + "NUMBERVDCS": 0, + "SUNSENDPOINT": "http://localhost:9869", + "NAME": "zoneA", + "SELFENDPOINT": null, + "ONENAME": "oneadminA", + "ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==" + } + ] + } +} \ No newline at end of file diff --git a/src/ozones/test/examples/vdc/vdc0.json b/src/ozones/test/examples/vdc/vdc0.json new file mode 100644 index 0000000000..b716f24472 --- /dev/null +++ b/src/ozones/test/examples/vdc/vdc0.json @@ -0,0 +1,12 @@ +{ + "VDC": { + "ID": 1, + "ACLS": "2,3,4,5,6,7", + "HOSTS": "1,2,3", + "NAME": "vdcA", + "ZONES_ID": 1, + "GROUP_ID": 100, + "VDCADMINNAME": "vdcadminA", + "VDCADMIN_ID": 2 + } +} \ No newline at end of file diff --git a/src/ozones/test/examples/zone/zone0.json b/src/ozones/test/examples/zone/zone0.json new file mode 100644 index 0000000000..6b8d182e36 --- /dev/null +++ b/src/ozones/test/examples/zone/zone0.json @@ -0,0 +1,14 @@ +{ + "ZONE": { + "ID": 1, + "ENDPOINT": "http://localhost:2666/RPC2", + "SUNSENDPOINT": "http://localhost:9869", + "VDCS": [ + + ], + "NAME": "zoneA", + "SELFENDPOINT": null, + "ONENAME": "oneadminA", + "ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==" + } +} \ No newline at end of file diff --git a/src/ozones/test/spec/VDCManagement_spec.rb b/src/ozones/test/spec/VDCManagement_spec.rb index 832fd8a37d..35be54b574 100644 --- a/src/ozones/test/spec/VDCManagement_spec.rb +++ b/src/ozones/test/spec/VDCManagement_spec.rb @@ -29,6 +29,8 @@ require 'command_parser' require 'ozones_helper/zones_helper.rb' require 'ozones_helper/vdc_helper.rb' +TESTS_PATH = File.dirname(__FILE__)+"/../" + module OZones describe "oZones server regarding VDCs" do @@ -39,12 +41,12 @@ module OZones VDCHelper.new("vdc", "ozonesadmin","ozonespassword") @clientA = OpenNebula::Client.new(File.read( - File.dirname(__FILE__)+"/../etc/one_auth_a"), + TESTS_PATH+"etc/one_auth_a"), "http://localhost:2666/RPC2") @clientB = OpenNebula::Client.new(File.read( - File.dirname(__FILE__)+"/../etc/one_auth_b"), - "http://localhost:2667/RPC2") + TESTS_PATH+"etc/one_auth_b"), + "http://localhost:2667/RPC2") hostA=OpenNebula::Host.new(OpenNebula::Host.build_xml, @clientA) hostA.allocate("hostA1","im_dummy","vmm_dummy","tm_dummy","dummy") @@ -59,15 +61,14 @@ module OZones end it "should be able to create a couple of zones" do - @zonehelper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneA.template")[0].should eql(0) - @zonehelper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneB.template")[0].should eql(0) + rc = @zonehelper.create_resource(TESTS_PATH+"templates/zoneA.template") + rc[0].should eql(0) + rc = @zonehelper.create_resource(TESTS_PATH+"templates/zoneB.template") + rc[0].should eql(0) end - it "should be able to create one vdc with the apropiate ONE resources" do - @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcA.template", + it "should be able to create one vdc with apropiate ONE resources" do + @vdchelper.create_resource(TESTS_PATH+"templates/vdcA.template", {:force => false})[0].should eql(0) upool = OpenNebula::UserPool.new(@clientA) @@ -98,25 +99,46 @@ module OZones end it "should be able to create a couple of VDCs" do - @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcB.template", + @vdchelper.create_resource(TESTS_PATH+"templates/vdcB.template", {:force => false})[0].should eql(0) - @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcC.template", + @vdchelper.create_resource(TESTS_PATH+"templates/vdcC.template", {:force => false})[0].should eql(0) end it "should fail when creating an existing VDC" do - @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdcA.template", + @vdchelper.create_resource(TESTS_PATH+"templates/vdcA.template", {:force => false})[0].should eql(-1) end it "should fail when creating a VDC upon a non existing zone" do - @vdchelper.create_resource(File.dirname(__FILE__)+ - "/../templates/vdc.no.zone.template", + @vdchelper.create_resource(TESTS_PATH+"templates/vdc.no.zone.template", {:force => false})[0].should eql(-1) end + it "should be able to retrieve the vdc pool" do + vdcpool = @vdchelper.list_pool({:json => true}) + vdcpool[0].should eql(0) + vdcpool[1].should eql(File.read(TESTS_PATH+"examples/pool/vdcpool0.json")) + end + + it "should be able to retrieve a particular vdc" do + vdc = @vdchelper.show_resource(1, {:json => true}) + vdc[0].should eql(0) + vdc[1].should eql(File.read(TESTS_PATH+"examples/vdc/vdc0.json")) + end + + it "should allow deleting a vdc" do + rc = @vdchelper.delete_resource(3, {}) + rc[0].should eql(0) + rc = @vdchelper.list_pool({:json => true}) + rc[0].should eql(0) + rc[1].should eql(File.read(TESTS_PATH+ + "examples/pool/vdcpool_deleted.json")) + end + + it "should fail on non-existing vdc deletion" do + rc = @vdchelper.delete_resource(7, {}) + rc[0].should eql(-1) + end end end diff --git a/src/ozones/test/spec/ZoneManagement_spec.rb b/src/ozones/test/spec/ZoneManagement_spec.rb index cf18a2d1ed..e60e5caf11 100644 --- a/src/ozones/test/spec/ZoneManagement_spec.rb +++ b/src/ozones/test/spec/ZoneManagement_spec.rb @@ -28,36 +28,71 @@ $: << RUBY_LIB_LOCATION+"/cli" require 'command_parser' require 'ozones_helper/zones_helper.rb' +TESTS_PATH = File.dirname(__FILE__)+"/../" + module OZones describe "oZones server regarding zones" do before(:all) do - @helper = ZonesHelper.new("zone", "ozonesadmin","ozonespassword") - @badhelper = ZonesHelper.new("zone", "wronguser","wrongpassword") + @helper = ZonesHelper.new("zone", "ozonesadmin","ozonespassword") + @badhelper = ZonesHelper.new("zone", "wronguser","wrongpassword") end - + it "should be able to create a couple of zones" do - @helper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneA.template")[0].should eql(0) - @helper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneB.template")[0].should eql(0) - end - + rc = @helper.create_resource(TESTS_PATH+"templates/zoneA.template") + rc[0].should eql(0) + + @helper.create_resource(TESTS_PATH+"templates/zoneB.template") + rc[0].should eql(0) + end + it "should fail with wrong zones templates" do - @helper.create_resource(File.dirname(__FILE__)+ - "/../templates/zone.wrong.credentials.template")[0].should eql(-1) - @helper.create_resource(File.dirname(__FILE__)+ - "/../templates/zone.wrong.endpoint.template")[0].should eql(-1) - end - + templ_path = "templates/zone.wrong.credentials.template" + rc = @helper.create_resource(TESTS_PATH+templ_path) + rc[0].should eql(-1) + + templ_path = "templates/zone.wrong.endpoint.template" + rc = @helper.create_resource(TESTS_PATH+templ_path) + rc[0].should eql(-1) + end + it "should fail when creating zones with existing name" do - @helper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneA.template")[0].should eql(-1) - end - + rc = @helper.create_resource(TESTS_PATH+"templates/zoneA.template") + rc[0].should eql(-1) + end + it "should refuse unauthorized requests" do - @badhelper.create_resource(File.dirname(__FILE__)+ - "/../templates/zoneA.template")[0].should eql(-1) - end + rc = @badhelper.create_resource(TESTS_PATH+ + "templates/zoneA.template") + rc[0].should eql(-1) + end + + it "should be able to retrieve the zone pool" do + zonepool = @helper.list_pool({:json => true}) + zonepool[0].should eql(0) + zonepool[1].should eql(File.read(TESTS_PATH+ + "examples/pool/zonepool0.json")) + end + + it "should be able to retrieve a particular zone" do + zone = @helper.show_resource(1,{:json => true}) + zone[0].should eql(0) + zone[1].should eql(File.read(TESTS_PATH+"examples/zone/zone0.json")) + end + + it "should allow deleting a zone" do + rc = @helper.delete_resource(2, {}) + rc[0].should eql(0) + rc = @helper.list_pool({:json => true}) + rc[0].should eql(0) + rc[1].should eql(File.read(TESTS_PATH+ + "examples/pool/zonepool_deleted.json")) + end + + it "should fail on non existing zone deletion" do + rc = @helper.delete_resource(7, {}) + rc[0].should eql(-1) + end + end -end \ No newline at end of file +end diff --git a/src/ozones/test/test.sh b/src/ozones/test/test.sh index a1822faffc..d6de0d2f42 100755 --- a/src/ozones/test/test.sh +++ b/src/ozones/test/test.sh @@ -51,13 +51,6 @@ for j in `ls ./spec/*_spec.rb` ; do done if (($CODE == 0)); then - # Terminate ONEs - ONE_LOCATION=$ONE_LOCATION_A oneA/bin/one stop - ONE_LOCATION=$ONE_LOCATION_B oneB/bin/one stop - - # Stop oZones - ONE_LOCATION=$ONE_LOCATION_A oneA/bin/ozones-server stop - # Delete directories rm -rf oneA rm -rf oneB From c62c2d02972d268ed154e4ac655ad094a6076c83 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Sat, 10 Mar 2012 18:44:36 +0100 Subject: [PATCH 53/64] Bug #1161: Wrong calls to Image.[non]persistent Persistency actions are of type "multiple", therefore they expect an array of elements. As only the ID string was passed, action was iterated for all the chars in the ID. --- src/sunstone/public/js/plugins/images-tab.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 02e441da56..7834fed26a 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -988,8 +988,8 @@ function setupImageTemplateUpdateDialog(){ var old_persistent = is_persistent_image(id); var new_persistent = $('#image_template_update_persistent',dialog).is(':checked'); if (old_persistent != new_persistent){ - if (new_persistent) Sunstone.runAction("Image.persistent",id); - else Sunstone.runAction("Image.nonpersistent",id); + if (new_persistent) Sunstone.runAction("Image.persistent",[id]); + else Sunstone.runAction("Image.nonpersistent",[id]); }; var permissions = $('.permissions_table',dialog); @@ -1067,9 +1067,9 @@ function setupImageActionCheckboxes(){ var $this = $(this) var id=$this.attr('elem_id'); if ($this.attr('checked')) - Sunstone.runAction("Image.persistent",id); + Sunstone.runAction("Image.persistent",[id]); else - Sunstone.runAction("Image.nonpersistent",id); + Sunstone.runAction("Image.nonpersistent",[id]); return true; }); From fa61ff4e727913735179bd8345d504bf8c2439c2 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 15 Mar 2012 12:57:47 +0100 Subject: [PATCH 54/64] Bug #1168: Fix error reporting in Ozones client --- src/ozones/Client/lib/zona.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ozones/Client/lib/zona.rb b/src/ozones/Client/lib/zona.rb index d22a8270c4..7aae83c1ab 100644 --- a/src/ozones/Client/lib/zona.rb +++ b/src/ozones/Client/lib/zona.rb @@ -283,7 +283,7 @@ EOT begin str << "Body: " << OZonesJSON.parse_json(value.body, - "error")["message"] + "error")[:message] rescue str.gsub!("\nBody:","") end From 447bc1849d74065bd2751ce30f106277ac82117b Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 26 Mar 2012 12:06:00 +0200 Subject: [PATCH 55/64] Sunstone: minor bugfixes. Show host tab for regular users. --- src/sunstone/etc/sunstone-plugins.yaml | 3 +-- src/sunstone/public/js/plugins/clusters-tab.js | 2 +- .../public/js/plugins/datastores-tab.js | 8 +++++--- src/sunstone/public/js/plugins/hosts-tab.js | 18 ++++++++++++------ src/sunstone/public/js/plugins/vnets-tab.js | 2 +- 5 files changed, 20 insertions(+), 13 deletions(-) diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index bc724898ba..7330791c4e 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -54,10 +54,9 @@ :user: :group: - plugins/hosts-tab.js: - :ALL: false + :ALL: true :user: :group: - oneadmin: true - plugins/datastores-tab.js: :ALL: true :user: diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index b0cccd6aaa..3de0de0bfe 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -453,7 +453,7 @@ function removeClusterMenus(){ // Sunstone.removeMainTab('cluster_vnets_tab_n',true); // Sunstone.removeMainTab('cluster_datastores_tab_n',true); // Sunstone.removeMainTab('cluster_hosts_tab_n',true); - Sunstone.removeMainTab('cluster_tab_n',true); + Sunstone.removeMainTab('cluster_tab_-',true); for (var i=0; i < data.length; i++){ var id = data[i][1]; diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 854bbba145..d7470dd7d8 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -271,7 +271,8 @@ var datastore_buttons = { "Datastore.update_dialog" : { type: "action", text: tr("Update properties"), - alwaysActive: true + alwaysActive: true, + condition: mustBeAdmin, }, "Datastore.addtocluster" : { type: "confirm_with_select", @@ -296,7 +297,8 @@ var datastore_buttons = { }, "Datastore.delete" : { type: "confirm", - text: tr("Delete") + text: tr("Delete"), + condition: mustBeAdmin } } @@ -443,7 +445,7 @@ function updateDatastoreInfo(request,ds){ \ \ '+tr("Cluster")+'\ - '+(element.CLUSTER.length ? element.CLUSTER : "-")+'\ + '+(info.CLUSTER.length ? info.CLUSTER : "-")+'\ \ \ '+tr("DS Mad")+'\ diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 0abc980a5b..147e793ef5 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -271,30 +271,36 @@ var host_buttons = { }, "Host.create_dialog" : { type: "create_dialog", - text: tr("+ New") + text: tr("+ New"), + condition: mustBeAdmin }, "Host.update_dialog" : { type: "action", text: tr("Update a template"), - alwaysActive: true + alwaysActive: true, + condition: mustBeAdmin }, "Host.addtocluster" : { type: "confirm_with_select", text: tr("Select cluster"), select: clusters_sel, tip: tr("Select the destination cluster:"), + condition: mustBeAdmin }, "Host.enable" : { type: "action", - text: tr("Enable") + text: tr("Enable"), + condition: mustBeAdmin }, "Host.disable" : { type: "action", - text: tr("Disable") + text: tr("Disable"), + condition: mustBeAdmin }, "Host.delete" : { type: "confirm", - text: tr("Delete host") + text: tr("Delete host"), + condition: mustBeAdmin } }; @@ -475,7 +481,7 @@ function updateHostInfo(request,host){ \ \ ' + tr("Cluster") + '\ - '+(host.CLUSTER.length ? host.CLUSTER : "-")+'\ + '+(host_info.CLUSTER.length ? host_info.CLUSTER : "-")+'\ \ \ ' + tr("State") + '\ diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index d65f672ebe..8f9a2d1b5d 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -566,7 +566,7 @@ function updateVNetworkInfo(request,vn){ \ \ '+tr("Cluster")+'\ - '+(network.CLUSTER.length ? network.CLUSTER : "-")+'\ + '+(vn_info.CLUSTER.length ? vn_info.CLUSTER : "-")+'\ \ \ '+tr("Owner")+'\ From fd4f8c87e07c92e81609614b0c0b7ba8b343c790 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 26 Mar 2012 12:49:25 +0200 Subject: [PATCH 56/64] Sunstone: Fixes related to clusters Adapt dashboards for cluster none. Do not show cluster info in infraestructure dashboard for non oneadmin users. --- .../public/js/plugins/clusters-tab.js | 75 +++++++++++++++++++ src/sunstone/public/js/plugins/infra-tab.js | 11 +-- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index 3de0de0bfe..676507df49 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -366,7 +366,82 @@ function clusterTabContent(cluster_json) { vnets_list = '
  • '+cluster.VNETS.ID+' - '+getVNetName(cluster.VNETS.ID)+'
  • '; */ + //special case for cluster none, simplified dashboard + if (cluster.ID == "-"){ + var html_code = '\ +\ +\ +\ +\ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Cluster information") + '

    \ +
    \ +\ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
    ' + tr("ID") + ''+cluster.ID+'
    ' + tr("Name") + ''+cluster.NAME+'
    \ +\ +
    \ +
    \ +
    \ +
    \ +

    ' + tr("Hosts") + '

    \ + \ +
    \ +
    \ +\ + \ + \ + \ + \ + \ + \ +
    \ +
    \ +

    ' + tr("Datastores") + '

    \ + \ +
    \ +
    \ +
    \ +

    ' + tr("Virtual Networks") + '

    \ + \ +
    \ +
    \ +
    \ +'; + return html_code; + }; + //end cluster none special html var html_code = '\ \ diff --git a/src/sunstone/public/js/plugins/infra-tab.js b/src/sunstone/public/js/plugins/infra-tab.js index 49e3782ed7..0b52418572 100644 --- a/src/sunstone/public/js/plugins/infra-tab.js +++ b/src/sunstone/public/js/plugins/infra-tab.js @@ -15,7 +15,7 @@ /* -------------------------------------------------------------------------- */ var infra_tab_content = -'
    \ +'
    \ \ \ \
    \ \ @@ -26,7 +26,7 @@ var infra_tab_content =
    \ \
    \ - \ + \ \ \ \ @@ -54,7 +54,7 @@ var infra_tab_content =

    ' + tr("Quickstart") + '

    \
    \


    \ - '+tr("Create new Cluster")+'
    \ + '+tr("Create new Cluster")+'
    \ '+tr("Create new Host")+'
    \ '+tr("Create new Datastore")+'
    \ '+tr("Create new Virtual Network")+'
    \ @@ -72,7 +72,7 @@ var infra_tab_content =

    \

    ' + tr("Infrastructure resources") + '

    \
    \ -

    '+tr("The Infrastructure menu allows management of Hosts, Datastores, Virtual Networks and the Clusters they are placed in. The Clusters node can be expanded, and resources can be managed for each cluster.")+'

    \ +

    '+tr("The Infrastructure menu allows management of Hosts, Datastores, Virtual Networks. Users in the oneadmin group can manage clusters as well.")+'

    \

    '+tr("You can find further information on the following links:")+'

    \
      \
    • Host subsystem
    • \ @@ -117,5 +117,6 @@ function updateInfraDashboard(what,json_info){ }; $(document).ready(function(){ - + if (!mustBeAdmin()) + $('table#infra_dashboard .cluster_related', main_tabs_context).hide(); }); \ No newline at end of file From 8d68721a590603e0591bb989e67a2b48e49b8f75 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 26 Mar 2012 13:10:47 +0200 Subject: [PATCH 57/64] Sunstone: Append submenus after parents menu. Allows more freedom in the loading order of plugins. Submenus will always be added after parent menu item, or after parents submenus items (so it keeps order). --- src/sunstone/etc/sunstone-plugins.yaml | 10 +++++----- src/sunstone/public/js/sunstone.js | 14 +++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/sunstone/etc/sunstone-plugins.yaml b/src/sunstone/etc/sunstone-plugins.yaml index 7330791c4e..edde7af592 100644 --- a/src/sunstone/etc/sunstone-plugins.yaml +++ b/src/sunstone/etc/sunstone-plugins.yaml @@ -53,6 +53,11 @@ :ALL: true :user: :group: +- plugins/clusters-tab.js: + :ALL: false + :user: + :group: + oneadmin: true - plugins/hosts-tab.js: :ALL: true :user: @@ -65,8 +70,3 @@ :ALL: true :user: :group: -- plugins/clusters-tab.js: - :ALL: false - :user: - :group: - oneadmin: true diff --git a/src/sunstone/public/js/sunstone.js b/src/sunstone/public/js/sunstone.js index df9659a96c..20e82c3909 100644 --- a/src/sunstone/public/js/sunstone.js +++ b/src/sunstone/public/js/sunstone.js @@ -465,7 +465,19 @@ function insertTab(tab_name){ $('div#'+tab_name,main_tabs_context).html(tab_info.content); - $('div#menu ul#navigation').append('
    • '+tab_info.title+'
    • '); + var li_item = '
    • '+tab_info.title+'
    • '; + + //if this is a submenu... + if (parent.length) { + var children = $('div#menu ul#navigation li.'+parent); + //if there are other submenus, insert after last of them + if (children.length) + $(children[children.length-1]).after(li_item); + else //instert after parent menu + $('div#menu ul#navigation li#li_'+parent).after(li_item); + } else { //not a submenu, instert in the end + $('div#menu ul#navigation').append(li_item); + }; if (parent){ //this is a subtab $('div#menu li#li_'+tab_name).hide();//hide by default From 04e907bc784540d8b2587474e26443cdf11dca9f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 27 Mar 2012 13:34:32 +0200 Subject: [PATCH 58/64] Feature #1181: Add ip column to vms view. --- src/sunstone/public/js/plugins/vms-tab.js | 28 ++++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index ff5815c3fe..c8210bea4b 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -63,6 +63,7 @@ var vms_tab_content =
    \ \ \ + \ \ \ \ @@ -619,7 +620,21 @@ function vmShow(req) { // Returns a human readable running time for a VM function str_start_time(vm){ return pretty_time(vm.STIME); -} +}; + +function ip_str(vm){ + var nic = vm.TEMPLATE.NIC; + var ip = '--'; + if ($.isArray(nic)) { + ip = ''; + $.each(nic, function(index,value){ + ip += value.IP+'
    '; + }); + } else if (nic && nic.IP) { + ip = nic.IP; + }; + return ip; +}; // Returns an array formed by the information contained in the vm_json // and ready to be introduced in a dataTable @@ -650,10 +665,11 @@ function vMachineElementArray(vm_json){ vm.CPU, humanize_size(vm.MEMORY), hostname, + ip_str(vm), str_start_time(vm), vncIcon(vm) ]; -} +}; //Creates a listener for the TDs of the VM table @@ -1284,9 +1300,9 @@ $(document).ready(function(){ "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0,6,7] }, - { "sWidth": "35px", "aTargets": [1,10] }, - { "sWidth": "150px", "aTargets": [5,9] }, - { "sWidth": "100px", "aTargets": [2,3] } + { "sWidth": "35px", "aTargets": [1,11] }, + { "sWidth": "150px", "aTargets": [5,10] }, + { "sWidth": "100px", "aTargets": [2,3,9] } ], "oLanguage": (datatable_lang != "") ? { @@ -1297,7 +1313,7 @@ $(document).ready(function(){ dataTable_vMachines.fnClearTable(); addElement([ spinner, - '','','','','','','','','',''],dataTable_vMachines); + '','','','','','','','','','',''],dataTable_vMachines); Sunstone.runAction("VM.list"); setupCreateVMDialog(); From aa0469acf677d5baf8d1b0f8af295897edcdc03d Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 27 Mar 2012 15:46:36 +0200 Subject: [PATCH 59/64] Feature #1179: Add vm history to vm tab --- src/sunstone/public/js/opennebula.js | 23 ++++-- src/sunstone/public/js/plugins/vms-tab.js | 90 ++++++++++++++++++++--- src/sunstone/public/js/sunstone-util.js | 14 ++++ 3 files changed, 113 insertions(+), 14 deletions(-) diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index eb4f149d30..8507ab0b08 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -46,21 +46,24 @@ var OpenNebula = { { switch(type) { - case "HOST","host": + case "HOST": + case "host": return ["INIT", "MONITORING", "MONITORED", "ERROR", "DISABLED"][value]; break; - case "HOST_SIMPLE","host_simple": + case "HOST_SIMPLE": + case "host_simple": return ["ON", "ON", "ON", "ERROR", "OFF"][value]; break; - case "VM","vm": + case "VM": + case "vm": return ["INIT", "PENDING", "HOLD", @@ -70,7 +73,8 @@ var OpenNebula = { "DONE", "FAILED"][value]; break; - case "VM_LCM","vm_lcm": + case "VM_LCM": + case "vm_lcm": return ["LCM_INIT", "PROLOG", "BOOT", @@ -89,7 +93,8 @@ var OpenNebula = { "CLEANUP", "UNKNOWN"][value]; break; - case "IMAGE","image": + case "IMAGE": + case "image": return ["INIT", "READY", "USED", @@ -97,6 +102,14 @@ var OpenNebula = { "LOCKED", "ERROR"][value]; break; + case "VM_MIGRATE_REASON": + case "vm_migrate_reason": + return ["NONE", + "ERROR", + "STOP_RESUME", + "USER", + "CANCEL"][value]; + break; default: return; } diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index c8210bea4b..455d2a39d5 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -593,6 +593,10 @@ var vm_info_panel = { "vm_log_tab" : { title: tr("VM log"), content: "" + }, + "vm_history_tab" : { + title: tr("History information"), + content: "", } } @@ -627,11 +631,11 @@ function ip_str(vm){ var ip = '--'; if ($.isArray(nic)) { ip = ''; - $.each(nic, function(index,value){ - ip += value.IP+'
    '; - }); + $.each(nic, function(index,value){ + ip += value.IP+'
    '; + }); } else if (nic && nic.IP) { - ip = nic.IP; + ip = nic.IP; }; return ip; }; @@ -719,7 +723,69 @@ function updateVMachinesView(request, vmachine_list){ updateView(vmachine_list_array,dataTable_vMachines); updateDashboard("vms",vmachine_list); updateVResDashboard("vms",vmachine_list); -} +}; + +function generateHistoryTable(vm){ + var html = '
    '+tr("CPU")+''+tr("Memory")+''+tr("Hostname")+''+tr("IPs")+''+tr("Start Time")+''+tr("VNC Access")+'
    \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + '; + + var history = []; + + if ($.isArray(vm.HISTORY_RECORDS.HISTORY)) + history = vm.HISTORY_RECORDS.HISTORY; + else if (vm.HISTORY_RECORDS.HISTORY.SEQ) + history = [vm.HISTORY_RECORDS.HISTORY]; + + var now = Math.round(new Date().getTime() / 1000); + + for (var i=0; i < history.length; i++){ + // :TIME time calculations copied from onevm_helper.rb + var stime = parseInt(history[i].STIME, 10); + + var etime = parseInt(history[i].ETIME, 10) + etime = etime == 0 ? now : etime; + + var dtime = etime - stime; + // end :TIME + + //:PTIME + var stime2 = parseInt(history[i].PSTIME, 10); + var etime2; + var ptime2 = parseInt(history[i].PETIME, 10); + if (stime2 == 0) + etime2 = 0; + else + etime2 = ptime2 == 0 ? now : ptime2; + var dtime2 = etime2 - stime2; + + //end :PTIME + + + html += ' \ + \ + \ + \ + \ + \ + \ + \ + ' + }; + html += '\ +
    '+tr("Sequence")+''+tr("Hostname")+''+tr("Reason")+''+tr("State change time")+''+tr("Total time")+''+tr("Prolog time")+'
    '+history[i].SEQ+''+history[i].HOSTNAME+''+OpenNebula.Helper.resource_state("VM_MIGRATE_REASON",parseInt(history[i].REASON, 10))+''+pretty_time(history[i].STIME)+''+pretty_time_runtime(dtime)+''+pretty_time_runtime(dtime2)+'
    '; + return html; + +}; // Refreshes the information panel for a VM @@ -821,7 +887,7 @@ function updateVMInfo(request,vm){
    ' - } + }; var template_tab = { title: tr("VM Template"), @@ -830,21 +896,27 @@ function updateVMInfo(request,vm){ '+tr("VM template")+''+ prettyPrintJSON(vm_info.TEMPLATE)+ '' - } + }; var log_tab = { title: tr("VM log"), content: '
    '+spinner+'
    ' - } + }; var monitoring_tab = { title: tr("Monitoring information"), content: generateMonitoringDivs(vm_graphs,"vm_monitor_") - } + }; + + var history_tab = { + title: tr("History information"), + content: generateHistoryTable(vm_info), + }; Sunstone.updateInfoPanelTab("vm_info_panel","vm_info_tab",info_tab); Sunstone.updateInfoPanelTab("vm_info_panel","vm_template_tab",template_tab); Sunstone.updateInfoPanelTab("vm_info_panel","vm_log_tab",log_tab); + Sunstone.updateInfoPanelTab("vm_info_panel","vm_history_tab",history_tab); Sunstone.updateInfoPanelTab("vm_info_panel","vm_monitoring_tab",monitoring_tab); //Pop up the info panel and asynchronously get vm_log and stats diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 22064569de..7877635b51 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -60,6 +60,20 @@ function pretty_time_axis(time){ return hour + ":" + mins + ":" + secs;// + " " + month + "/" + day; } +function pretty_time_runtime(time){ + var d = new Date(); + d.setTime(time*1000); + + var secs = pad(d.getUTCSeconds(),2); + var hour = pad(d.getUTCHours(),2); + var mins = pad(d.getUTCMinutes(),2); + var day = d.getUTCDate()-1; + var month = pad(d.getUTCMonth()+1,2); //getMonths returns 0-11 + var year = d.getUTCFullYear(); + + return day + "d " + hour + ":" + mins;// + ":" + secs;// + " " + month + "/" + day; +} + //returns a human readable size in Kilo, Mega, Giga or Tera bytes function humanize_size(value) { if (typeof(value) === "undefined") { From ef97c118c8b57af6e05733bb7a0e1ef4cdf45e00 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 27 Mar 2012 16:19:41 +0200 Subject: [PATCH 60/64] Sunstone: hide manual disk and network addition when creating vm templates --- src/sunstone/public/js/plugins/hosts-tab.js | 4 ---- .../public/js/plugins/templates-tab.js | 21 ++++++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 147e793ef5..dd4423c77a 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -499,10 +499,6 @@ function updateHostInfo(request,host){ '+ tr("VN MAD") +'\ '+host_info.VN_MAD+'\ \ - \ - '+ tr("TM MAD") +'\ - '+host_info.TM_MAD+'\ - \ \ \ \ diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index f7496b0892..59d7165900 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -186,7 +186,7 @@ var create_template_tmpl = '
    \

    '+tr("Add disks/images")+'

    \
    \
    '+tr("Disks")+'\ -
    \ +