From 86d70574d8dd8c30226aa39087eb4bfc210c4a0b Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 23 Apr 2012 12:55:05 +0200 Subject: [PATCH 01/14] fix new jQuery 1.7.2 includes in UIs --- src/cloud/occi/lib/ui/templates/login.html | 2 +- src/cloud/occi/lib/ui/views/index.erb | 2 +- src/ozones/Server/templates/index.html | 2 +- src/ozones/Server/templates/login.html | 2 +- src/sunstone/templates/login.html | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cloud/occi/lib/ui/templates/login.html b/src/cloud/occi/lib/ui/templates/login.html index 8bf6d0c005..7fb6b3e456 100644 --- a/src/cloud/occi/lib/ui/templates/login.html +++ b/src/cloud/occi/lib/ui/templates/login.html @@ -5,7 +5,7 @@ - + diff --git a/src/cloud/occi/lib/ui/views/index.erb b/src/cloud/occi/lib/ui/views/index.erb index 2ec20cb5cf..86dd776731 100644 --- a/src/cloud/occi/lib/ui/views/index.erb +++ b/src/cloud/occi/lib/ui/views/index.erb @@ -10,7 +10,7 @@ - + diff --git a/src/ozones/Server/templates/index.html b/src/ozones/Server/templates/index.html index afbc1c3039..cf434eab15 100644 --- a/src/ozones/Server/templates/index.html +++ b/src/ozones/Server/templates/index.html @@ -10,7 +10,7 @@ - + diff --git a/src/ozones/Server/templates/login.html b/src/ozones/Server/templates/login.html index d1001aaaa4..0624092c43 100644 --- a/src/ozones/Server/templates/login.html +++ b/src/ozones/Server/templates/login.html @@ -5,7 +5,7 @@ - + diff --git a/src/sunstone/templates/login.html b/src/sunstone/templates/login.html index 1dc5352d14..c708ec0ea5 100644 --- a/src/sunstone/templates/login.html +++ b/src/sunstone/templates/login.html @@ -6,7 +6,7 @@ - + From c7721e814dac16b1f5d38e3ce603c854a060338f Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 23 Apr 2012 17:12:10 +0200 Subject: [PATCH 02/14] Sunstone: require image target when adding image to VM template. Autofill when attribute is present in image template. Include special input for target in image creation form. --- src/sunstone/public/js/plugins/images-tab.js | 19 +++++++++++++++---- .../public/js/plugins/templates-tab.js | 11 ++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index 4fe86d4051..d7a5ebe693 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -36,6 +36,7 @@ var images_tab_content = '\ '+tr("Persistent")+'\ '+tr("Status")+'\ '+tr("#VMS")+'\ + '+tr("Target")+'\ \ \ \ @@ -108,6 +109,11 @@ var create_image_tmpl = \
'+tr("Specific image mapping driver. KVM: raw, qcow2. XEN: tap:aio, file:")+'
\ \ +
\ + \ + \ +
'+tr("Target on which the image will be mounted at. For example: hda, sdb...")+'
\ +
\ \
\
\ @@ -544,7 +550,8 @@ function imageElementArray(image_json){ parseInt(image.PERSISTENT) ? '' : '', OpenNebula.Helper.resource_state("image",image.STATE), - image.RUNNING_VMS + image.RUNNING_VMS, + image.TEMPLATE.TARGET ? image.TEMPLATE.TARGET : '--' ]; } @@ -899,6 +906,10 @@ function setupCreateImageDialog(){ if (driver.length) img_json["DRIVER"] = driver; + var target = $('#img_target',this).val(); + if (target) + img_json["TARGET"] = target; + switch ($('#src_path_select input:checked',this).val()){ case "path": path = $('#img_path',this).val(); @@ -1144,10 +1155,10 @@ $(document).ready(function(){ "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0,2,3,9,10] }, - { "sWidth": "35px", "aTargets": [1,6,11] }, + { "sWidth": "35px", "aTargets": [1,6,11,12] }, { "sWidth": "100px", "aTargets": [5,7] }, { "sWidth": "150px", "aTargets": [8] }, - { "bVisible": false, "aTargets": [6,8]} + { "bVisible": false, "aTargets": [6,8,12]} ], "oLanguage": (datatable_lang != "") ? { @@ -1158,7 +1169,7 @@ $(document).ready(function(){ dataTable_images.fnClearTable(); addElement([ spinner, - '','','','','','','','','','',''],dataTable_images); + '','','','','','','','','','','',''],dataTable_images); Sunstone.runAction("Image.list"); setupCreateImageDialog(); diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 993f3980fb..8411a95bd8 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -208,7 +208,7 @@ var create_template_tmpl = '
\ \
'+tr("Type of disk device to emulate: ide, scsi")+'
\
\ -
\ +
\ \ \
'+tr("Device to map image disk. If set, it will overwrite the default device mapping")+'
\ @@ -1405,6 +1405,11 @@ function setupCreateTemplateDialog(){ $('#IMAGE', section_disks).change(function(){ var uname = getValue($(this).val(),4,2,dataTable_images); $('input#IMAGE_UNAME',section_disks).val(uname); + var target = getValue($(this).val(),4,12,dataTable_images); + if (target && target != "--") + $('input#TARGET',section_disks).val(target); + else + $('input#TARGET',section_disks).val(''); }); //Depending on adding a disk or a image we need to show/hide @@ -1420,16 +1425,12 @@ function setupCreateTemplateDialog(){ $('.add_image',section_disks).attr('disabled','disabled'); $('.add_disk',section_disks).show(); $('.add_disk',section_disks).removeAttr('disabled'); - $('#TARGET',section_disks).parent().removeClass(opt_class); - $('#TARGET',section_disks).parent().addClass(man_class); break; case "image": $('.add_disk',section_disks).hide(); $('.add_disk',section_disks).attr('disabled','disabled'); $('.add_image',section_disks).show(); $('.add_image',section_disks).removeAttr('disabled'); - $('#TARGET',section_disks).parent().removeClass(man_class); - $('#TARGET',section_disks).parent().addClass(opt_class); break; } $('#SIZE',section_disks).parent().hide(); From 889249a6af8a78bd43452042302b7bd3b4405e31 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 24 Apr 2012 11:45:27 +0200 Subject: [PATCH 03/14] Bug #1043: Prevent VNC dialog from closing with ESC key in Sunstone and SelfService --- src/cloud/occi/lib/ui/public/js/plugins/compute.js | 1 + src/sunstone/public/js/plugins/vms-tab.js | 1 + 2 files changed, 2 insertions(+) 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 cedf1210e1..15eec4d581 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -997,6 +997,7 @@ function setupVNC(){ modal:true, height:500, resizable:true, + closeOnEscape: false }); $('#sendCtrlAltDelButton',dialog).click(function(){ diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index 8a936c904a..e4ec4f57d8 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -1300,6 +1300,7 @@ function setupVNC(){ modal:true, height:500, resizable:true, + closeOnEscape: false }); $('#sendCtrlAltDelButton',dialog).click(function(){ From 5fcb907a9ecfc8b561f125dfe10a55e1b4e204f4 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 24 Apr 2012 12:44:21 +0200 Subject: [PATCH 04/14] Feature #1218: add IP column to compute list in Selfservice --- .../occi/lib/ui/public/js/plugins/compute.js | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 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 15eec4d581..5b99c81c9f 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -63,6 +63,7 @@ var vms_tab_content = '+tr("All")+'\ '+tr("ID")+'\ '+tr("Name")+' / '+tr("State")+'\ + '+tr("IP")+'\ \ \ \ @@ -397,6 +398,20 @@ function str_start_time(vm){ return pretty_time(vm.STIME); } +function ip_str(vm){ + var nic = vm.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 function vMachineElementArray(vm_json){ @@ -416,7 +431,8 @@ function vMachineElementArray(vm_json){ return [ '', id, - VMStateBulletStr(vm_json) + name + VMStateBulletStr(vm_json) + name, + ip_str(vm) ]; } @@ -454,7 +470,7 @@ function addVMachineElement(request,vm_json){ var id = vm_json.COMPUTE.ID; var element = vMachineElementArray(vm_json); addElement(element,dataTable_vMachines); - Sunstone.runAction("VM.showstate",id); + Sunstone.runAction("VM.show",id); } @@ -1098,6 +1114,7 @@ $(document).ready(function(){ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, { "sWidth": "35px", "aTargets": [1] }, + { "sWidth": "110px", "aTargets": [3] }, ], "oLanguage": (datatable_lang != "") ? { @@ -1108,7 +1125,7 @@ $(document).ready(function(){ dataTable_vMachines.fnClearTable(); addElement([ spinner, - '',''],dataTable_vMachines); + '','',''],dataTable_vMachines); Sunstone.runAction("VM.list"); //setupCreateVMDialog(); From 01cef094183a0da70b19dcb730106950de85aa60 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 25 Apr 2012 13:13:17 +0200 Subject: [PATCH 05/14] Feature #1207: Add custom input field for host drivers and user auth driver --- src/sunstone/public/js/plugins/hosts-tab.js | 67 ++++++++++++++++++--- src/sunstone/public/js/plugins/users-tab.js | 17 +++++- 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 1376a8566d..431985711f 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -84,7 +84,11 @@ var create_host_tmpl = \ \ \ + \ \ +
\ + \ +
\
\
\ \ @@ -94,18 +98,28 @@ var create_host_tmpl = \ \ \ + \ \ +
\ + \ + \ +
\
\
\ \ \ +
\ + \ + \ +
\
\
\ \ @@ -595,9 +609,35 @@ function setupCreateHostDialog(){ $('button',dialog).button(); + $('input[name="custom_vmm_mad"],'+ + 'input[name="custom_im_mad"],'+ + 'input[name="custom_vnm_mad"]',dialog).parent().hide(); + + $('select#vmm_mad',dialog).change(function(){ + if ($(this).val()=="custom") + $('input[name="custom_vmm_mad"]').parent().show(); + else + $('input[name="custom_vmm_mad"]').parent().hide(); + }); + + $('select#im_mad',dialog).change(function(){ + if ($(this).val()=="custom") + $('input[name="custom_im_mad"]').parent().show(); + else + $('input[name="custom_im_mad"]').parent().hide(); + }); + + $('select#vnm_mad',dialog).change(function(){ + if ($(this).val()=="custom") + $('input[name="custom_vnm_mad"]').parent().show(); + else + $('input[name="custom_vnm_mad"]').parent().hide(); + }); + //Handle the form submission $('#create_host_form',dialog).submit(function(){ - if (!($('#name',this).val().length)){ + var name = $('#name',this).val(); + if (!name){ notifyError(tr("Host name missing!")); return false; } @@ -605,12 +645,19 @@ function setupCreateHostDialog(){ var cluster_id = $('#host_cluster_id',this).val(); if (!cluster_id) cluster_id = "-1"; + var vmm_mad = $('select#vmm_mad',this).val(); + vmm_mad = vmm_mad == "custom" ? $('input[name="custom_vmm_mad"]').val() : vmm_mad; + var im_mad = $('select#im_mad',this).val(); + im_mad = im_mad == "custom" ? $('input[name="custom_im_mad"]').val() : im_mad; + var vnm_mad = $('select#vnm_mad',this).val(); + vnm_mad = vnm_mad == "custom" ? $('input[name="custom_vnm_mad"]').val() : vnm_mad; + var host_json = { "host": { - "name": $('#name',this).val(), - "vm_mad": $('#vmm_mad',this).val(), - "vnm_mad": $('#vnm_mad',this).val(), - "im_mad": $('#im_mad',this).val(), + "name": name, + "vm_mad": vmm_mad, + "vnm_mad": vnm_mad, + "im_mad": im_mad, "cluster_id": cluster_id } }; diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 1585513a31..d1f4aa34ab 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -60,7 +60,12 @@ var create_user_tmpl = \ \ \ + \ \ +
\ + \ +
\ +
\
\
\
\ @@ -444,15 +449,25 @@ function setupCreateUserDialog(){ $('button',dialog).button(); + $('input[name="custom_auth"]',dialog).parent().hide(); + $('select#driver').change(function(){ + if ($(this).val() == "custom") + $('input[name="custom_auth"]',dialog).parent().show(); + else + $('input[name="custom_auth"]',dialog).parent().hide(); + }); + $('#create_user_form',dialog).submit(function(){ var user_name=$('#username',this).val(); var user_password=$('#pass',this).val(); var driver = $('#driver', this).val(); + if (driver == 'custom') + driver = $('input[name="custom_auth"]').val(); if (!user_name.length || !user_password.length){ notifyError(tr("User name and password must be filled in")); return false; - } + }; var user_json = { "user" : { "name" : user_name, From 6cf2c019ff0fec234beb668fcf20e9d3611837c3 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 26 Apr 2012 17:04:20 +0200 Subject: [PATCH 06/14] Feature #1253: Modify row click behaviour in Sunstone When clicking on a row with CTRL it will be checked/unchecked. When >= 1 rows are already selected, subsequent clicks on rows will (un)select them instead of triggering the info dialog. --- src/sunstone/public/js/plugins/acls-tab.js | 1 + .../public/js/plugins/clusters-tab.js | 2 +- .../public/js/plugins/datastores-tab.js | 17 +----------- src/sunstone/public/js/plugins/groups-tab.js | 12 +-------- src/sunstone/public/js/plugins/hosts-tab.js | 18 +------------ src/sunstone/public/js/plugins/images-tab.js | 20 +------------- .../public/js/plugins/templates-tab.js | 17 +----------- src/sunstone/public/js/plugins/users-tab.js | 16 +---------- src/sunstone/public/js/plugins/vms-tab.js | 18 +------------ src/sunstone/public/js/plugins/vnets-tab.js | 19 +------------ src/sunstone/public/js/sunstone-util.js | 27 +++++++++++++++++++ 11 files changed, 37 insertions(+), 130 deletions(-) diff --git a/src/sunstone/public/js/plugins/acls-tab.js b/src/sunstone/public/js/plugins/acls-tab.js index a61ca0082d..d53b4f81f7 100644 --- a/src/sunstone/public/js/plugins/acls-tab.js +++ b/src/sunstone/public/js/plugins/acls-tab.js @@ -517,4 +517,5 @@ $(document).ready(function(){ tableCheckboxesListener(dataTable_acls); //shortenedInfoFields('#datatable_acls'); + infoListener(dataTable_acls); }) diff --git a/src/sunstone/public/js/plugins/clusters-tab.js b/src/sunstone/public/js/plugins/clusters-tab.js index f08e6ab9ad..e2d9d1e400 100644 --- a/src/sunstone/public/js/plugins/clusters-tab.js +++ b/src/sunstone/public/js/plugins/clusters-tab.js @@ -864,5 +864,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_clusters); tableCheckboxesListener(dataTable_clusters); -// clusterInfoListener(); + infoListener(dataTable_clusters); }); diff --git a/src/sunstone/public/js/plugins/datastores-tab.js b/src/sunstone/public/js/plugins/datastores-tab.js index 996a85ba3c..80f760a018 100644 --- a/src/sunstone/public/js/plugins/datastores-tab.js +++ b/src/sunstone/public/js/plugins/datastores-tab.js @@ -356,21 +356,6 @@ function datastoreElementArray(element_json){ ]; } -function datastoreInfoListener(){ - - $('#tbodydatastores tr',dataTable_datastores).live("click", function(e){ - if ($(e.target).is('input') || $(e.target).is('a img')) {return true;} - - var aData = dataTable_datastores.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("Datastore.showinfo",id); - return false; - }); -}; - function updateDatastoreSelect(){ datastores_select = makeSelectOptions(dataTable_datastores, 1, @@ -703,7 +688,7 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_datastores); tableCheckboxesListener(dataTable_datastores); - datastoreInfoListener(); + infoListener(dataTable_datastores,'Datastore.showinfo'); $('div#menu li#li_datastores_tab').live('click',function(){ dataTable_datastores.fnFilter('',5); diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 5689390462..8f6152ae29 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -179,17 +179,6 @@ function groupElementArray(group_json){ users_str ]; } -// function groupInfoListener(){ -// $('#groups_tab #tbodygroups tr',main_tabs_context).live("click",function(e){ -// //do nothing if we are clicking a checkbox! -// if ($(e.target).is('input')) {return true;} -// var aData = dataTable_groups.fnGetData(this); -// var id = $(aData[0]).val(); -// Sunstone.runAction("Group.showinfo",id); -// return false; -// }); -// } - function updateGroupSelect(){ groups_select = makeSelectOptions(dataTable_groups, 1,//id_col @@ -302,4 +291,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_groups); tableCheckboxesListener(dataTable_groups); + infoListener(dataTable_groups); }) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index 431985711f..e7536daede 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -425,22 +425,6 @@ function hostElementArray(host_json){ ]; } -//Listen to clicks on the tds of the tables and shows the info dialogs. -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;} - - var aData = dataTable_hosts.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("Host.showinfo",id); - return false; - }); -} - //updates the host select by refreshing the options in it function updateHostSelect(){ hosts_select = makeSelectOptions(dataTable_hosts, @@ -739,7 +723,7 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_hosts); tableCheckboxesListener(dataTable_hosts); - hostInfoListener(); + infoListener(dataTable_hosts, "Host.showinfo"); $('div#menu li#li_hosts_tab').live('click',function(){ dataTable_hosts.fnFilter('',3); diff --git a/src/sunstone/public/js/plugins/images-tab.js b/src/sunstone/public/js/plugins/images-tab.js index d7a5ebe693..ade3f02c2a 100644 --- a/src/sunstone/public/js/plugins/images-tab.js +++ b/src/sunstone/public/js/plugins/images-tab.js @@ -555,24 +555,6 @@ function imageElementArray(image_json){ ]; } -// Set up the listener on the table TDs to show the info panel -function imageInfoListener(){ - $('#tbodyimages tr',dataTable_images).live("click",function(e){ - var target = $(e.target); - - if (target.is('input') || target.is('select') || target.is('option')) - return true; - - var aData = dataTable_images.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("Image.showinfo",id); - return false; - }); -} - // Callback to update an element in the dataTable function updateImageElement(request, image_json){ var id = image_json.IMAGE.ID; @@ -1180,5 +1162,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_images); tableCheckboxesListener(dataTable_images); - imageInfoListener(); + infoListener(dataTable_images,'Image.showinfo'); }); diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 8411a95bd8..84be66f5fd 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -857,21 +857,6 @@ function templateElementArray(template_json){ ]; } -// Set up the listener on the table TDs to show the info panel -function templateInfoListener(){ - $('#tbodytemplates tr',dataTable_templates).live("click",function(e){ - if ($(e.target).is('input')) {return true;} - - var aData = dataTable_templates.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("Template.showinfo",id); - return false; - }); -} - //Updates the select input field with an option for each template function updateTemplateSelect(){ var templates_select = @@ -2178,5 +2163,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_templates); tableCheckboxesListener(dataTable_templates); - templateInfoListener(); + infoListener(dataTable_templates,'Template.showinfo'); }); diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index d1f4aa34ab..02ba240c94 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -342,20 +342,6 @@ function userElementArray(user_json){ ] }; -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, 1,//id_col @@ -571,5 +557,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_users); tableCheckboxesListener(dataTable_users); //shortenedInfoFields('#datatable_users'); - userInfoListener(); + infoListener(dataTable_users,'User.showinfo'); }); diff --git a/src/sunstone/public/js/plugins/vms-tab.js b/src/sunstone/public/js/plugins/vms-tab.js index e4ec4f57d8..3f621dbe2f 100644 --- a/src/sunstone/public/js/plugins/vms-tab.js +++ b/src/sunstone/public/js/plugins/vms-tab.js @@ -683,22 +683,6 @@ function vMachineElementArray(vm_json){ }; -//Creates a listener for the TDs of the VM table -function vMachineInfoListener(){ - - $('#tbodyvmachines tr',dataTable_vMachines).live("click", function(e){ - if ($(e.target).is('input') || $(e.target).is('a img')) {return true;} - - var aData = dataTable_vMachines.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("VM.showinfo",id); - return false; - }); -} - // Callback to refresh a single element from the list function updateVMachineElement(request, vm_json){ var id = vm_json.VM.ID; @@ -1410,5 +1394,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_vMachines); tableCheckboxesListener(dataTable_vMachines); - vMachineInfoListener(); + infoListener(dataTable_vMachines,'VM.showinfo'); }) \ No newline at end of file diff --git a/src/sunstone/public/js/plugins/vnets-tab.js b/src/sunstone/public/js/plugins/vnets-tab.js index 4b0f497747..8ef88a8811 100644 --- a/src/sunstone/public/js/plugins/vnets-tab.js +++ b/src/sunstone/public/js/plugins/vnets-tab.js @@ -496,23 +496,6 @@ function vNetworkElementArray(vn_json){ network.TOTAL_LEASES ]; } - -//Adds a listener to show the extended info when clicking on a row -function vNetworkInfoListener(){ - - $('#tbodyvnetworks tr',dataTable_vNetworks).live("click", function(e){ - 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; - }); -} - //Callback to update a vnet element after an action on it function updateVNetworkElement(request, vn_json){ id = vn_json.VNET.ID; @@ -1209,7 +1192,7 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_vNetworks); tableCheckboxesListener(dataTable_vNetworks); - vNetworkInfoListener(); + infoListener(dataTable_vNetworks,'Network.showinfo'); $('div#menu li#li_vnets_tab').live('click',function(){ dataTable_vNetworks.fnFilter('',5); diff --git a/src/sunstone/public/js/sunstone-util.js b/src/sunstone/public/js/sunstone-util.js index 39fae61534..7a066f4b48 100644 --- a/src/sunstone/public/js/sunstone-util.js +++ b/src/sunstone/public/js/sunstone-util.js @@ -787,6 +787,33 @@ function popUpTemplateUpdateDialog(elem_str,select_items,sel_elems){ return false; } + +//Shows run a custom action when clicking on rows. +function infoListener(dataTable, info_action){ + $('tbody tr',dataTable).live("click",function(e){ + if ($(e.target).is('input')) {return true;} + + var aData = dataTable.fnGetData(this); + var id = $(aData[0]).val(); + if (!id) return true; + + var count = $('tbody .check_item:checked', dataTable).length; + + if (info_action){ + if (e.ctrlKey || count >= 1) + $('.check_item',this).trigger('click'); + else { + popDialogLoading(); + Sunstone.runAction(info_action,id) + }; + } else { + $('.check_item',this).trigger('click'); + }; + + return false; + }); +} + function mustBeAdmin(){ return gid == 0; } From 50bc0711a5a2cc8d459daec00228a5aa8c97b457 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 26 Apr 2012 17:07:39 +0200 Subject: [PATCH 07/14] Feature #1256: Show graphics section in template creation for vmware --- src/sunstone/public/js/plugins/templates-tab.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/sunstone/public/js/plugins/templates-tab.js b/src/sunstone/public/js/plugins/templates-tab.js index 84be66f5fd..dcf42eb96c 100644 --- a/src/sunstone/public/js/plugins/templates-tab.js +++ b/src/sunstone/public/js/plugins/templates-tab.js @@ -435,31 +435,31 @@ var create_template_tmpl = '
\

'+tr("Add Graphics")+'

\
\
'+tr("Graphics")+'\ -
\ +
\ \ \ -
\ +
'+tr("VMware supports VNC only")+'
\
\ -
\ +
\ \ \
'+tr("IP to listen on")+'
\
\ -
\ +
\ \ \
'+tr("Port for the VNC server")+'
\
\ -
\ +
\ \ \
'+tr("Password for the VNC server")+'
\
\ -
\ +
\ \ \
'+tr("Keyboard configuration locale to use in the VNC display")+'
\ @@ -997,7 +997,6 @@ function setupCreateTemplateDialog(){ //hide non common sections $(section_inputs).hide(); - $(section_graphics).hide(); switch(ui.index){ case 0: @@ -1085,7 +1084,6 @@ function setupCreateTemplateDialog(){ $('input#TYPE', section_raw).val("kvm"); $(section_inputs).show(); - $(section_graphics).show(); }; // Using XEN wizard. @@ -1121,7 +1119,6 @@ function setupCreateTemplateDialog(){ $('select#BUS',section_disks).html(bus_opts); $('input#TYPE', section_raw).val("xen"); - $(section_graphics).show(); }; //VMWare wizard From 30fbadd5046c3ceb2da7370819a155c1e50960c7 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 27 Apr 2012 11:55:32 +0200 Subject: [PATCH 08/14] Bug #1246: Add max cpu to host info view --- src/sunstone/public/js/plugins/hosts-tab.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sunstone/public/js/plugins/hosts-tab.js b/src/sunstone/public/js/plugins/hosts-tab.js index e7536daede..2c482ea121 100644 --- a/src/sunstone/public/js/plugins/hosts-tab.js +++ b/src/sunstone/public/js/plugins/hosts-tab.js @@ -533,6 +533,10 @@ function updateHostInfo(request,host){ ' + tr("Used Mem (allocated)") + '\ '+humanize_size(host_info.HOST_SHARE.MAX_USAGE)+'\ \ + \ + ' + tr("Max CPU") + '\ + '+host_info.HOST_SHARE.MAX_CPU+'\ + \ \ ' + tr("Used CPU (real)") + '\ '+host_info.HOST_SHARE.USED_CPU+'\ From 0e02730af849d6c7cae1e6909385232784bd9104 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 27 Apr 2012 11:57:09 +0200 Subject: [PATCH 09/14] Feature #1253: Ctrl + click select row for sunstone and selfservice --- .../occi/lib/ui/public/js/plugins/compute.js | 18 +---------------- .../occi/lib/ui/public/js/plugins/network.js | 18 +---------------- .../occi/lib/ui/public/js/plugins/storage.js | 20 +------------------ .../Server/public/js/plugins/vdcs-tab.js | 16 +-------------- .../Server/public/js/plugins/zones-tab.js | 16 +-------------- 5 files changed, 5 insertions(+), 83 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 5b99c81c9f..dabafb3edc 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/compute.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/compute.js @@ -437,22 +437,6 @@ function vMachineElementArray(vm_json){ } -//Creates a listener for the TDs of the VM table -function vMachineInfoListener(){ - - $('#tbodyvmachines tr',dataTable_vMachines).live("click", function(e){ - if ($(e.target).is('input') || $(e.target).is('a img')) {return true;} - - var aData = dataTable_vMachines.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("VM.showinfo",id); - return false; - }); -} - // Callback to refresh a single element from the list function updateVMachineElement(request, vm_json){ var id = vm_json.COMPUTE.ID; @@ -1135,7 +1119,7 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_vMachines); tableCheckboxesListener(dataTable_vMachines); - vMachineInfoListener(); + infoListener(dataTable_vMachines,'VM.showinfo'); $('#li_vms_tab').click(function(){ popUpVMDashboard(); 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 b909d84d68..a19f9046bc 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/network.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/network.js @@ -233,22 +233,6 @@ function vNetworkElementArray(vn_json){ }; -//Adds a listener to show the extended info when clicking on a row -function vNetworkInfoListener(){ - - $('#tbodyvnetworks tr',dataTable_vNetworks).live("click", function(e){ - 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; - }); -} - //Callback to update a vnet element after an action on it function updateVNetworkElement(request, vn_json){ id = vn_json.NETWORK.ID; @@ -443,7 +427,7 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_vNetworks); tableCheckboxesListener(dataTable_vNetworks); - vNetworkInfoListener(); + infoListener(dataTable_vNetworks,'Network.showinfo'); $('#li_vnets_tab').click(function(){ popUpVNetDashboard(); 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 d21f7b285a..c42a3ab7dc 100644 --- a/src/cloud/occi/lib/ui/public/js/plugins/storage.js +++ b/src/cloud/occi/lib/ui/public/js/plugins/storage.js @@ -300,24 +300,6 @@ function imageElementArray(image_json){ ]; } -// Set up the listener on the table TDs to show the info panel -function imageInfoListener(){ - $('#tbodyimages tr',dataTable_images).live("click",function(e){ - var target = $(e.target); - - if (target.is('input') || target.is('select') || target.is('option')) - return true; - - var aData = dataTable_images.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("Image.showinfo",id); - return false; - }); -} - // Callback to update an element in the dataTable function updateImageElement(request, image_json){ var id = image_json.STORAGE.ID; @@ -629,7 +611,7 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_images); tableCheckboxesListener(dataTable_images); - imageInfoListener(); + infoListener(dataTable_images, 'Image.showinfo'); $('#li_images_tab').click(function(){ popUpImageDashboard(); diff --git a/src/ozones/Server/public/js/plugins/vdcs-tab.js b/src/ozones/Server/public/js/plugins/vdcs-tab.js index 29bf077e10..773417ab31 100644 --- a/src/ozones/Server/public/js/plugins/vdcs-tab.js +++ b/src/ozones/Server/public/js/plugins/vdcs-tab.js @@ -307,20 +307,6 @@ function vdcElementArray(vdc_json){ ]; } -function vdcInfoListener() { - $("#tbodyvdcs tr").live("click", function(e){ - if ($(e.target).is('input')) {return true;} - - var aData = dataTable_vdcs.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("VDC.showinfo",id); - return false; - }); -} - function deleteVDCElement(req){ deleteElement(dataTable_vdcs,'#vdc_'+req.request.data); } @@ -930,5 +916,5 @@ $(document).ready(function(){ setVDCAutorefresh(); initCheckAllBoxes(dataTable_vdcs); tableCheckboxesListener(dataTable_vdcs); - vdcInfoListener(); + infoListener(dataTable_vdcs,'VDC.showinfo'); }); \ No newline at end of file diff --git a/src/ozones/Server/public/js/plugins/zones-tab.js b/src/ozones/Server/public/js/plugins/zones-tab.js index 54b1049694..8402f2f5d4 100644 --- a/src/ozones/Server/public/js/plugins/zones-tab.js +++ b/src/ozones/Server/public/js/plugins/zones-tab.js @@ -275,20 +275,6 @@ function zoneElementArray(zone_json){ ]; } -function zoneInfoListener(){ - $("#tbodyzones tr").live("click", function(e){ - if ($(e.target).is('input')) {return true;} - - var aData = dataTable_zones.fnGetData(this); - var id = $(aData[0]).val(); - if (!id) return true; - - popDialogLoading(); - Sunstone.runAction("Zone.showinfo",id); - return false; - }); -} - function updateZoneSelect(){ zones_select = makeSelectOptions(dataTable_zones,1,2,-1,"",-1); } @@ -744,5 +730,5 @@ $(document).ready(function(){ initCheckAllBoxes(dataTable_zones); tableCheckboxesListener(dataTable_zones); - zoneInfoListener(); + infoListener(dataTable_zones,'Zone.showinfo'); }); \ No newline at end of file From a935e147fbe9cd26b96666f1de6b7389a01f1d94 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 30 Apr 2012 13:48:40 +0200 Subject: [PATCH 10/14] Bug #1213: Handle errors when listing aggregated resources and zone resources when one or several zones are down. --- src/ozones/Server/lib/OZones/AggregatedPool.rb | 16 +++++++--------- src/ozones/Server/lib/OZones/Zones.rb | 8 +++++++- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/ozones/Server/lib/OZones/AggregatedPool.rb b/src/ozones/Server/lib/OZones/AggregatedPool.rb index 6ac96ce8a8..b098b8d1bb 100644 --- a/src/ozones/Server/lib/OZones/AggregatedPool.rb +++ b/src/ozones/Server/lib/OZones/AggregatedPool.rb @@ -34,26 +34,24 @@ module OZones zone_pool_hash = zone.to_hash["ZONE"] - client = OpenNebula::Client.new("#{zone.ONENAME}:#{zone.ONEPASS}", - zone.ENDPOINT) + client = OpenNebula::Client.new("#{zone.ONENAME}:#{zone.ONEPASS}", + zone.ENDPOINT) pool = factory(client) - if OpenNebula.is_error?(pool) - zone_pool_hash.merge!(pool.to_hash) - next - end - rc = pool.info - if !rc zone_pool_hash.merge!(pool.to_hash) + elsif OpenNebula.is_error?(rc) + error = "Error communicating with #{zone.NAME}." + error << " Retrieving #{self.class.name.split('::').last}: " + error << "#{rc.to_str}" + zone_pool_hash.merge!({:error => {:message => error}}) else zone_pool_hash.merge!(rc.to_hash) end @sup_aggregated_pool[@tag]["ZONE"] << zone_pool_hash - } end diff --git a/src/ozones/Server/lib/OZones/Zones.rb b/src/ozones/Server/lib/OZones/Zones.rb index 95300c0d0d..34b48e655a 100644 --- a/src/ozones/Server/lib/OZones/Zones.rb +++ b/src/ozones/Server/lib/OZones/Zones.rb @@ -199,7 +199,13 @@ module OZones return [404, error.to_json] end - pool.info + rc = pool.info + if OpenNebula.is_error?(rc) + error = "Error communicating with #{@zone.NAME}." + error << " Retrieving #{pool_kind} pool: " + error << "#{rc.to_str}" + return [500, OZones::Error.new(error).to_json] + end return [200, pool.to_json] end From edd607baa9be19ef3d5c39f27b43853fa4705dbb Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 30 Apr 2012 13:56:45 +0200 Subject: [PATCH 11/14] Bug #1215: Add SUNSENDPOINT AND SELFENDPOINT to onezone show command --- src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb b/src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb index 71d85c7610..d255d0b65a 100644 --- a/src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb +++ b/src/ozones/Client/lib/cli/ozones_helper/zones_helper.rb @@ -44,6 +44,8 @@ class ZonesHelper < OZonesHelper::OZHelper puts str % ["ZONE ADMIN ",zone[:ONENAME].to_s] puts str % ["ZONE PASS ", zone[:ONEPASS].to_s] puts str % ["ENDPOINT ", zone[:ENDPOINT].to_s] + puts str % ["SUNSENDPOINT ", zone[:SUNSENDPOINT].to_s] + puts str % ["SELFENDPOINT ", zone[:SELFENDPOINT].to_s] puts str % ["# VDCS ", zone[:VDCS].size.to_s] puts From 351ae0113862eb37c84804cd240b88c9ef869405 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Mon, 30 Apr 2012 14:06:04 +0200 Subject: [PATCH 12/14] Bug #1217: correct hosts, dss, vnets lists in onevdc show --- src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb index 8f8a98b026..808a099e3f 100644 --- a/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb +++ b/src/ozones/Client/lib/cli/ozones_helper/vdc_helper.rb @@ -157,9 +157,9 @@ class VDCHelper < OZonesHelper::OZHelper puts str % ["CLUSTER_ID ", vdc[:CLUSTER_ID].to_s] puts str % ["GROUP_ID ", vdc[:GROUP_ID].to_s] puts str % ["VDCADMIN ", vdc[:VDCADMINNAME].to_s] - puts str % ["HOSTS ", vdc[:RESOURCES][:HOSTS].to_s] - puts str % ["DATASTORES ", vdc[:RESOURCES][:DATASTORES].to_s] - puts str % ["NETWORKS ", vdc[:RESOURCES][:NETWORKS].to_s] + puts str % ["HOSTS ", vdc[:RESOURCES][:HOSTS].join(',')] + puts str % ["DATASTORES ", vdc[:RESOURCES][:DATASTORES].join(',')] + puts str % ["NETWORKS ", vdc[:RESOURCES][:NETWORKS].join(',')] puts return 0 From 26c51cb3a3b48174625e56f08e3219dfd24ae19d Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Thu, 3 May 2012 13:41:04 +0200 Subject: [PATCH 13/14] Feature #1125: Move ozones to Sequel instead of Datamapper --- src/ozones/Server/lib/OZones/ApacheWritter.rb | 4 +- src/ozones/Server/lib/OZones/VDC.rb | 79 +++++++++++-------- src/ozones/Server/lib/OZones/Zones.rb | 52 +++++++----- src/ozones/Server/models/Auth.rb | 19 +++-- src/ozones/Server/models/OzonesServer.rb | 13 ++- src/ozones/Server/ozones-server.rb | 21 +++-- 6 files changed, 109 insertions(+), 79 deletions(-) diff --git a/src/ozones/Server/lib/OZones/ApacheWritter.rb b/src/ozones/Server/lib/OZones/ApacheWritter.rb index ca3ae1fdd3..47832c93ba 100644 --- a/src/ozones/Server/lib/OZones/ApacheWritter.rb +++ b/src/ozones/Server/lib/OZones/ApacheWritter.rb @@ -24,8 +24,8 @@ module OZones def update htaccess = "RewriteEngine On\n" - OZones::Zones.all.each{|zone| - zone.vdcs.all.each{|vdc| + OZones::Zones.each{|zone| + zone.vdcs.each{|vdc| htaccess << "RewriteRule ^#{vdc.NAME} " + "#{zone.ENDPOINT} [P]\n" diff --git a/src/ozones/Server/lib/OZones/VDC.rb b/src/ozones/Server/lib/OZones/VDC.rb index 46ec6de56f..263f11eabc 100644 --- a/src/ozones/Server/lib/OZones/VDC.rb +++ b/src/ozones/Server/lib/OZones/VDC.rb @@ -22,28 +22,42 @@ module OZones # ID, NAME, the GROUP backing the VDC, the admin credentials and the VDC # resources. VDC resources are stored in JSON document in the DB and used as # a hash in the VDC. - class Vdc - include DataMapper::Resource + class Vdc < Sequel::Model include OpenNebulaJSON::JSONUtils extend OpenNebulaJSON::JSONUtils - property :ID, Serial - property :NAME, String, :required => true, :unique => true - property :GROUP_ID, Integer - property :VDCADMINNAME, String, :required => true - property :VDCADMIN_ID, Integer - property :CLUSTER_ID, Integer - property :RESOURCES, Text + plugin :schema + plugin :validation_helpers - belongs_to :zones + set_schema do + primary_key :ID + String :NAME, :unique => true + Integer :GROUP_ID + foreign_key :ZONES_ID, :zones, :key => :ID + String :VDCADMINNAME + Integer :VDCADMIN_ID + Integer :CLUSTER_ID + String :RESOURCES, :text => true + + end + + create_table unless table_exists? + + many_to_one :zone, :class => 'OZones::Zones', :key => :ZONES_ID + + def validate + super + validates_presence [:NAME, :VDCADMINNAME] + validates_unique :NAME + end def resources rsrc_json = self.RESOURCES parser = JSON.parser.new(rsrc_json, {:symbolize_names => true}) parser.parse - end - + end + def resources=(rsrc_hash) self.RESOURCES = JSON.generate(rsrc_hash) end @@ -55,11 +69,7 @@ module OZones zonePoolHash["VDC_POOL"]["VDC"] = Array.new unless self.all.empty? self.all.each{ |vdc| - # Hack! zones_ID does not respect the "all capital letters" policy - attrs = vdc.attributes.clone - - attrs[:ZONES_ID] = vdc.attributes[:zones_ID] - attrs.delete(:zones_ID) + attrs = vdc.values.clone rsrc_json = attrs.delete(:RESOURCES) parser = JSON.parser.new(rsrc_json, {:symbolize_names=>true}) @@ -74,11 +84,7 @@ module OZones def to_hash vdc_attributes = Hash.new - # Hack! zones_ID does not respect the "all capital letters" policy - attrs = attributes.clone - - attrs[:ZONES_ID] = attributes[:zones_ID] - attrs.delete(:zones_ID) + attrs = @values.clone rsrc_json = attrs.delete(:RESOURCES) parser = JSON.parser.new(rsrc_json, {:symbolize_names=>true}) @@ -99,9 +105,9 @@ module OZones ####################################################################### # Constants ####################################################################### - VDC_ATTRS = [:VDCADMINNAME, - :VDCADMINPASS, - :NAME, + VDC_ATTRS = [:VDCADMINNAME, + :VDCADMINPASS, + :NAME, :CLUSTER_ID, :RESOURCES] @@ -111,13 +117,13 @@ module OZones #Creates an OpenNebula VDC, using its ID, vdcid and the associated zone def initialize(vdcid, zone = nil) if vdcid != -1 - @vdc = Vdc.get(vdcid) + @vdc = Vdc[vdcid] if !@vdc raise "VDC with id #{vdcid} not found." end - @zone = OZones::Zones.get(@vdc.zones_ID) + @zone = OZones::Zones[@vdc.ZONES_ID] else @zone = zone end @@ -150,9 +156,17 @@ module OZones #------------------------------------------------------------------- # Create a vdc record & check cluster consistency #------------------------------------------------------------------- - @vdc = Vdc.new + begin - @vdc.attributes = vdc_data + + @vdc = Vdc.new + + @vdc.update(vdc_data) + @vdc.ZONES_ID = @zone.ID + + rescue => e + return OpenNebula::Error.new(e.message) + end rc = resources_in_cluster?(rsrc) @@ -198,10 +212,11 @@ module OZones rc, acl_ids = create_acls(rules) return rollback(group, user, acl_ids,rc) if OpenNebula.is_error?(rc) - OzonesServer::logger.debug {"ACLs #{acl_ids} created"} + OzonesServer::logger.debug {"ACLs #{acl_ids} created"} rsrc[:ACLS] = acl_ids @vdc.resources = rsrc + @vdc.save return true end @@ -283,10 +298,8 @@ module OZones #Update the VDC Record # ------------------------------------------------------------------ begin - @vdc.raise_on_save_failure = true @vdc.resources = rsrc_hash - - @vdc.save + @vdc.save(:raise_on_failure => true) rescue => e return OpenNebula::Error.new(e.message) end diff --git a/src/ozones/Server/lib/OZones/Zones.rb b/src/ozones/Server/lib/OZones/Zones.rb index 34b48e655a..25340469ed 100644 --- a/src/ozones/Server/lib/OZones/Zones.rb +++ b/src/ozones/Server/lib/OZones/Zones.rb @@ -16,29 +16,42 @@ module OZones - class Zones - include DataMapper::Resource + class Zones < Sequel::Model include OpenNebulaJSON::JSONUtils extend OpenNebulaJSON::JSONUtils + plugin :schema + plugin :validation_helpers + ####################################################################### # Data Model for the Zone ####################################################################### - property :ID, Serial - property :NAME, String, :required => true, :unique => true - property :ONENAME, String, :required => true - property :ONEPASS, String, :required => true - property :ENDPOINT, String, :required => true - property :SUNSENDPOINT, String - property :SELFENDPOINT, String + set_schema do + primary_key :ID + String :NAME, :unique => true + String :ONENAME + String :ONEPASS + String :ENDPOINT + String :SUNSENDPOINT + String :SELFENDPOINT + end - has n, :vdcs + create_table unless table_exists? + + one_to_many :vdcs, :class => 'OZones::Vdc', :key => :ZONES_ID ####################################################################### # Constants ####################################################################### ZONE_ATTRS = [:ONENAME, :ONEPASS, :ENDPOINT, :NAME] + def validate + super + validates_presence ZONE_ATTRS + validates_unique :NAME + end + + ####################################################################### # JSON Functions ####################################################################### @@ -47,11 +60,11 @@ module OZones zonePoolHash["ZONE_POOL"] = Hash.new zonePoolHash["ZONE_POOL"]["ZONE"] = Array.new unless self.all.empty? - self.all.each{|zone| - zattr = zone.attributes.clone + self.each{|zone| + zattr = zone.values.clone zattr[:ONEPASS] = Zones.encrypt(zattr[:ONEPASS]) - zattr[:NUMBERVDCS] = zone.vdcs.all.size + zattr[:NUMBERVDCS] = zone.vdcs.size zonePoolHash["ZONE_POOL"]["ZONE"] << zattr } @@ -62,12 +75,12 @@ module OZones def to_hash zattr = Hash.new - zattr["ZONE"] = attributes.clone + zattr["ZONE"] = @values.clone zattr["ZONE"][:ONEPASS] = Zones.encrypt(zattr["ZONE"][:ONEPASS]) zattr["ZONE"][:VDCS] = Array.new - self.vdcs.all.each{|vdc| - zattr["ZONE"][:VDCS]<< vdc.attributes.clone + self.vdcs.each{|vdc| + zattr["ZONE"][:VDCS]<< vdc.values.clone } return zattr @@ -111,10 +124,7 @@ module OZones # Create the zone begin zone = Zones.new - zone.raise_on_save_failure = true - - zone.attributes = zone_data - zone.save + zone.update(zone_data) rescue => e return OZones::Error.new(e.message) end @@ -165,7 +175,7 @@ module OZones ########################################################################## class OpenNebulaZone def initialize(zoneid) - @zone = Zones.get(zoneid) + @zone = Zones[zoneid] if !@zone raise "Error: Zone with id #{zoneid} not found" diff --git a/src/ozones/Server/models/Auth.rb b/src/ozones/Server/models/Auth.rb index 220c82a2b1..bda86623c9 100644 --- a/src/ozones/Server/models/Auth.rb +++ b/src/ozones/Server/models/Auth.rb @@ -14,12 +14,21 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -class Auth +class Auth < Sequel::Model + plugin :schema + plugin :validation_helpers - include DataMapper::Resource + set_schema do + primary_key :id + String :name, :unique => true + String :password + end - property :id, Serial - property :name, String, :required => true, :unique => true - property :password, String, :required => true + create_table unless table_exists? + def validate + super + validates_unique(:name) + validates_presence [:name, :password] + end end diff --git a/src/ozones/Server/models/OzonesServer.rb b/src/ozones/Server/models/OzonesServer.rb index 2777fe6532..ca58210ae1 100644 --- a/src/ozones/Server/models/OzonesServer.rb +++ b/src/ozones/Server/models/OzonesServer.rb @@ -36,7 +36,7 @@ class OzonesServer < CloudServer # Gets a VDC def get_vdc(id) - vdc = OZones::Vdc.get(id) + vdc = OZones::Vdc[id] if vdc return [200, vdc.to_json] @@ -53,7 +53,7 @@ class OzonesServer < CloudServer #Gets a zone def get_zone(id) - zone = OZones::Zones.get(id) + zone = OZones::Zones[id] if zone return [200, zone.to_json] @@ -101,7 +101,7 @@ class OzonesServer < CloudServer "Mandatory attribute zoneid missing.").to_json] end - zone = OZones::Zones.get(zoneid) + zone = OZones::Zones[zoneid] if !zone return [404, OZones::Error.new("Error: Couldn't create vdc. " \ "Zone #{zoneid} not found.").to_json] @@ -126,11 +126,10 @@ class OzonesServer < CloudServer #----------------------------------------------------------------------- #Update the zone and save the vdc #----------------------------------------------------------------------- - zone.raise_on_save_failure = true zone.vdcs << vdc.vdc begin - zone.save + zone.save(:raise_on_failture => true) rescue => e #vdc.clean_bootstrap logger.error {"create_vdc: #{e.resource.errors.inspect}"} @@ -231,7 +230,7 @@ class OzonesServer < CloudServer end def delete_zone(id, pr) - zone = OZones::Zones.get(id) + zone = OZones::Zones[id] if zone rc = zone.destroy @@ -264,7 +263,7 @@ class OzonesServer < CloudServer all_hosts = Array.new - zone.vdcs.all(:CLUSTER_ID =>c_id).each{ |vdc| + zone.vdcs(:CLUSTER_ID =>c_id).each{ |vdc| rsrc = vdc.resources if !rsrc[:HOSTS].empty? and vdc.ID != vdc_data[:ID] diff --git a/src/ozones/Server/ozones-server.rb b/src/ozones/Server/ozones-server.rb index 70eb42323a..dd9634a62e 100755 --- a/src/ozones/Server/ozones-server.rb +++ b/src/ozones/Server/ozones-server.rb @@ -51,7 +51,7 @@ require 'sinatra' require 'yaml' require 'rubygems' -require 'data_mapper' +require 'sequel' require 'digest/sha1' require 'OzonesServer' @@ -102,18 +102,16 @@ enable_logging OZONES_LOG, settings.config[:debug_level].to_i ############################################################################## # DB bootstrapping ############################################################################## -if config[:dbdebug] - DataMapper::Logger.new($stdout, :debug) -end -DataMapper.setup(:default, db_url) +DB = Sequel.connect(db_url) + +if config[:dbdebug] + DB.loggers << settings.logger +end require 'OZones' require 'Auth' -DataMapper.finalize -DataMapper.auto_upgrade! - if Auth.all.size == 0 if ENV['OZONES_AUTH'] && File.exist?(ENV['OZONES_AUTH']) credentials = IO.read(ENV['OZONES_AUTH']).strip.split(':') @@ -123,9 +121,10 @@ if Auth.all.size == 0 exit -1 end credentials[1] = Digest::SHA1.hexdigest(credentials[1]) - @auth=Auth.create({:name => credentials[0], - :password => credentials[1]}) - @auth.save + @auth=Auth.new + @auth.name = credentials[0] + @auth.password = credentials[1] + @auth.save(:raise_on_failure => true) else error_m = "oZones admin credentials not set, missing OZONES_AUTH file." settings.logger.error { error_m } From 77fe50271bfe7d5684bf0f70a99d6ac7900eb09b Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Fri, 4 May 2012 13:38:12 +0200 Subject: [PATCH 14/14] Ozones: update tests to work with latest developments --- src/ozones/test/examples/pool/vdcpool0.json | 68 +++++++++---------- .../test/examples/pool/vdcpool_deleted.json | 42 ++++++------ src/ozones/test/examples/pool/zonepool0.json | 28 ++++---- .../test/examples/pool/zonepool_deleted.json | 14 ++-- src/ozones/test/examples/vdc/vdc0.json | 16 ++--- src/ozones/test/examples/zone/zone0.json | 12 ++-- src/ozones/test/spec/VDCManagement_spec.rb | 25 +++++-- src/ozones/test/spec/ZoneManagement_spec.rb | 26 +++++-- 8 files changed, 132 insertions(+), 99 deletions(-) diff --git a/src/ozones/test/examples/pool/vdcpool0.json b/src/ozones/test/examples/pool/vdcpool0.json index a1bdeb5bb3..4029a5a990 100644 --- a/src/ozones/test/examples/pool/vdcpool0.json +++ b/src/ozones/test/examples/pool/vdcpool0.json @@ -2,13 +2,9 @@ "VDC_POOL": { "VDC": [ { - "NAME": "vdcA", + "VDCADMINNAME": "vdcadminA", "VDCADMIN_ID": 2, - "ID": 1, "RESOURCES": { - "DATASTORES": [ - 100 - ], "HOSTS": [ 0, 1, @@ -27,21 +23,21 @@ 8, 9, 10 - ] - }, - "GROUP_ID": 100, - "ZONES_ID": 1, - "VDCADMINNAME": "vdcadminA", - "CLUSTER_ID": 100 - }, - { - "NAME": "vdcB", - "VDCADMIN_ID": 2, - "ID": 2, - "RESOURCES": { + ], "DATASTORES": [ 100 - ], + ] + }, + "NAME": "vdcA", + "CLUSTER_ID": 100, + "ZONES_ID": 1, + "ID": 1, + "GROUP_ID": 100 + }, + { + "VDCADMINNAME": "vdcadminB", + "VDCADMIN_ID": 2, + "RESOURCES": { "HOSTS": [ 1 ], @@ -56,21 +52,21 @@ 6, 7, 8 - ] - }, - "GROUP_ID": 100, - "ZONES_ID": 2, - "VDCADMINNAME": "vdcadminB", - "CLUSTER_ID": 100 - }, - { - "NAME": "vdcC", - "VDCADMIN_ID": 3, - "ID": 3, - "RESOURCES": { + ], "DATASTORES": [ 100 - ], + ] + }, + "NAME": "vdcB", + "CLUSTER_ID": 100, + "ZONES_ID": 2, + "ID": 2, + "GROUP_ID": 100 + }, + { + "VDCADMINNAME": "vdcadminC", + "VDCADMIN_ID": 3, + "RESOURCES": { "HOSTS": [ 3 ], @@ -85,12 +81,16 @@ 15, 16, 17 + ], + "DATASTORES": [ + 100 ] }, - "GROUP_ID": 101, + "NAME": "vdcC", + "CLUSTER_ID": 100, "ZONES_ID": 1, - "VDCADMINNAME": "vdcadminC", - "CLUSTER_ID": 100 + "ID": 3, + "GROUP_ID": 101 } ] } diff --git a/src/ozones/test/examples/pool/vdcpool_deleted.json b/src/ozones/test/examples/pool/vdcpool_deleted.json index 9933c90dc9..1de8ad38a2 100644 --- a/src/ozones/test/examples/pool/vdcpool_deleted.json +++ b/src/ozones/test/examples/pool/vdcpool_deleted.json @@ -2,13 +2,9 @@ "VDC_POOL": { "VDC": [ { - "NAME": "vdcA", + "VDCADMINNAME": "vdcadminA", "VDCADMIN_ID": 2, - "ID": 1, "RESOURCES": { - "DATASTORES": [ - 100 - ], "HOSTS": [ 0, 1, @@ -27,21 +23,21 @@ 8, 9, 10 - ] - }, - "GROUP_ID": 100, - "ZONES_ID": 1, - "VDCADMINNAME": "vdcadminA", - "CLUSTER_ID": 100 - }, - { - "NAME": "vdcB", - "VDCADMIN_ID": 2, - "ID": 2, - "RESOURCES": { + ], "DATASTORES": [ 100 - ], + ] + }, + "NAME": "vdcA", + "CLUSTER_ID": 100, + "ZONES_ID": 1, + "ID": 1, + "GROUP_ID": 100 + }, + { + "VDCADMINNAME": "vdcadminB", + "VDCADMIN_ID": 2, + "RESOURCES": { "HOSTS": [ 1 ], @@ -56,12 +52,16 @@ 6, 7, 8 + ], + "DATASTORES": [ + 100 ] }, - "GROUP_ID": 100, + "NAME": "vdcB", + "CLUSTER_ID": 100, "ZONES_ID": 2, - "VDCADMINNAME": "vdcadminB", - "CLUSTER_ID": 100 + "ID": 2, + "GROUP_ID": 100 } ] } diff --git a/src/ozones/test/examples/pool/zonepool0.json b/src/ozones/test/examples/pool/zonepool0.json index 55e4228586..deb2b87d23 100644 --- a/src/ozones/test/examples/pool/zonepool0.json +++ b/src/ozones/test/examples/pool/zonepool0.json @@ -2,24 +2,24 @@ "ZONE_POOL": { "ZONE": [ { - "NAME": "zoneA", - "SUNSENDPOINT": "http://localhost:9869", - "SELFENDPOINT": null, - "ONENAME": "oneadminA", - "ID": 1, - "ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==", "ENDPOINT": "http://localhost:2666/RPC2", - "NUMBERVDCS": 0 + "SUNSENDPOINT": "http://localhost:9869", + "NAME": "zoneA", + "SELFENDPOINT": null, + "NUMBERVDCS": 0, + "ID": 1, + "ONENAME": "oneadminA", + "ONEPASS": "e/TkohQckqFcmcWFwrirUapdiLkg87GHPafKnxkzznk=" }, { - "NAME": "zoneB", - "SUNSENDPOINT": null, - "SELFENDPOINT": null, - "ONENAME": "oneadminB", - "ID": 2, - "ONEPASS": "8Si8vlo2P3qn5/SNxkMkDg==", "ENDPOINT": "http://localhost:2667/RPC2", - "NUMBERVDCS": 0 + "SUNSENDPOINT": null, + "NAME": "zoneB", + "SELFENDPOINT": null, + "NUMBERVDCS": 0, + "ID": 2, + "ONENAME": "oneadminB", + "ONEPASS": "DrnuZMnmOFVeYTXTVwTgEmOGw2orTjaU/f1NyuNKlQY=" } ] } diff --git a/src/ozones/test/examples/pool/zonepool_deleted.json b/src/ozones/test/examples/pool/zonepool_deleted.json index 0176e04da5..bf4910f018 100644 --- a/src/ozones/test/examples/pool/zonepool_deleted.json +++ b/src/ozones/test/examples/pool/zonepool_deleted.json @@ -2,14 +2,14 @@ "ZONE_POOL": { "ZONE": [ { - "NAME": "zoneA", - "SUNSENDPOINT": "http://localhost:9869", - "SELFENDPOINT": null, - "ONENAME": "oneadminA", - "ID": 1, - "ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==", "ENDPOINT": "http://localhost:2666/RPC2", - "NUMBERVDCS": 0 + "SUNSENDPOINT": "http://localhost:9869", + "NAME": "zoneA", + "SELFENDPOINT": null, + "NUMBERVDCS": 0, + "ID": 1, + "ONENAME": "oneadminA", + "ONEPASS": "e/TkohQckqFcmcWFwrirUapdiLkg87GHPafKnxkzznk=" } ] } diff --git a/src/ozones/test/examples/vdc/vdc0.json b/src/ozones/test/examples/vdc/vdc0.json index 35d7a92420..d07db9c90c 100644 --- a/src/ozones/test/examples/vdc/vdc0.json +++ b/src/ozones/test/examples/vdc/vdc0.json @@ -1,12 +1,8 @@ { "VDC": { - "NAME": "vdcA", + "VDCADMINNAME": "vdcadminA", "VDCADMIN_ID": 2, - "ID": 1, "RESOURCES": { - "DATASTORES": [ - 100 - ], "HOSTS": [ 0, 1, @@ -25,11 +21,15 @@ 8, 9, 10 + ], + "DATASTORES": [ + 100 ] }, - "GROUP_ID": 100, + "NAME": "vdcA", + "CLUSTER_ID": 100, "ZONES_ID": 1, - "VDCADMINNAME": "vdcadminA", - "CLUSTER_ID": 100 + "ID": 1, + "GROUP_ID": 100 } } \ No newline at end of file diff --git a/src/ozones/test/examples/zone/zone0.json b/src/ozones/test/examples/zone/zone0.json index 108a250402..b7788ca34f 100644 --- a/src/ozones/test/examples/zone/zone0.json +++ b/src/ozones/test/examples/zone/zone0.json @@ -1,14 +1,14 @@ { "ZONE": { - "NAME": "zoneA", + "ENDPOINT": "http://localhost:2666/RPC2", "SUNSENDPOINT": "http://localhost:9869", + "NAME": "zoneA", + "SELFENDPOINT": null, + "ID": 1, + "ONENAME": "oneadminA", "VDCS": [ ], - "SELFENDPOINT": null, - "ONENAME": "oneadminA", - "ID": 1, - "ONEPASS": "OkqWM2aSqbM/nlrdHGv3OA==", - "ENDPOINT": "http://localhost:2666/RPC2" + "ONEPASS": "e/TkohQckqFcmcWFwrirUapdiLkg87GHPafKnxkzznk=" } } \ 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 1d006721e3..8a5eeca459 100644 --- a/src/ozones/test/spec/VDCManagement_spec.rb +++ b/src/ozones/test/spec/VDCManagement_spec.rb @@ -154,13 +154,25 @@ module OZones 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")) + + got = vdcpool[1] + expected = File.read(TESTS_PATH+"examples/pool/vdcpool0.json") + + got = JSON.parser.new(got, {:symbolize_names => true}).parse + expected = JSON.parser.new(expected, {:symbolize_names => true}).parse + got.should eql(expected) 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")) + + got = vdc[1] + expected = File.read(TESTS_PATH+"examples/vdc/vdc0.json") + + got = JSON.parser.new(got, {:symbolize_names => true}).parse + expected = JSON.parser.new(expected, {:symbolize_names => true}).parse + got.should eql(expected) end it "should allow deleting a vdc" do @@ -168,8 +180,13 @@ module OZones 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")) + + got = rc[1] + expected = File.read(TESTS_PATH+"examples/pool/vdcpool_deleted.json") + + got = JSON.parser.new(got, {:symbolize_names => true}).parse + expected = JSON.parser.new(expected, {:symbolize_names => true}).parse + got.should eql(expected) end it "should fail on non-existing vdc deletion" do diff --git a/src/ozones/test/spec/ZoneManagement_spec.rb b/src/ozones/test/spec/ZoneManagement_spec.rb index 8826fef7c0..061aab2cf8 100644 --- a/src/ozones/test/spec/ZoneManagement_spec.rb +++ b/src/ozones/test/spec/ZoneManagement_spec.rb @@ -72,14 +72,25 @@ module OZones 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")) + + got = zonepool[1] + expected = File.read(TESTS_PATH+"examples/pool/zonepool0.json") + + got = JSON.parser.new(got, {:symbolize_names => true}).parse + expected = JSON.parser.new(expected, {:symbolize_names => true}).parse + got.should eql(expected) 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")) + + got = zone[1] + expected = File.read(TESTS_PATH+"examples/zone/zone0.json") + + got = JSON.parser.new(got, {:symbolize_names => true}).parse + expected = JSON.parser.new(expected, {:symbolize_names => true}).parse + got.should eql(expected) end it "should allow deleting a zone" do @@ -87,8 +98,13 @@ module OZones 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")) + + got = rc[1] + expected = File.read(TESTS_PATH+"examples/pool/zonepool_deleted.json") + + got = JSON.parser.new(got, {:symbolize_names => true}).parse + expected = JSON.parser.new(expected, {:symbolize_names => true}).parse + got.should eql(expected) end it "should fail on non existing zone deletion" do