From 374a9b6d770fa3ab36918f68aca50f06d5e639bc Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 26 Jun 2012 15:10:53 +0200 Subject: [PATCH 01/24] Bug #1313: Fix marketplace endpoint and error code handling (cherry picked from commit c62622ed6bd2bd61060132a8bdee4ef0d1f0e9d8) --- src/sunstone/etc/sunstone-server.conf | 2 +- src/sunstone/models/SunstoneMarketplace.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sunstone/etc/sunstone-server.conf b/src/sunstone/etc/sunstone-server.conf index 6c512329f7..5a06926b8f 100644 --- a/src/sunstone/etc/sunstone-server.conf +++ b/src/sunstone/etc/sunstone-server.conf @@ -93,4 +93,4 @@ # Marketplace endpoint # -:marketplace_url: http://marketplace.c12g.com/ +:marketplace_url: https://marketplace.c12g.com/appliance diff --git a/src/sunstone/models/SunstoneMarketplace.rb b/src/sunstone/models/SunstoneMarketplace.rb index 6f8745f5fa..c2dcad8217 100644 --- a/src/sunstone/models/SunstoneMarketplace.rb +++ b/src/sunstone/models/SunstoneMarketplace.rb @@ -30,7 +30,7 @@ module SunstoneMarketplace if CloudClient::is_error?(response) error = Error.new(response.to_s) - return [response.code, error.to_json] + return [response.code.to_i, error.to_json] end [200, response.body] @@ -47,9 +47,9 @@ module SunstoneMarketplace if CloudClient::is_error?(response) error = Error.new(response.to_s) - return [response.code, error.to_json] + return [response.code.to_i, error.to_json] end [200, response.body] end -end \ No newline at end of file +end From 0b2111d91138de510b6b88f298e4d43cf5930f64 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 26 Jun 2012 15:12:06 +0200 Subject: [PATCH 02/24] Feature #1303: Improve marketplace sunstone plugin Reduced duplicated code, make better use of Susntone actions. (cherry picked from commit 19413babfa1b286bdedf5cb93fad6c8bd7a074f2) --- src/sunstone/public/js/opennebula.js | 30 +++ .../public/js/plugins/marketplace-tab.js | 176 +++++++----------- 2 files changed, 96 insertions(+), 110 deletions(-) diff --git a/src/sunstone/public/js/opennebula.js b/src/sunstone/public/js/opennebula.js index c8c52b4f27..999d3d1c06 100644 --- a/src/sunstone/public/js/opennebula.js +++ b/src/sunstone/public/js/opennebula.js @@ -984,4 +984,34 @@ var OpenNebula = { OpenNebula.Action.show(params,OpenNebula.Datastore.resource,"template"); }, }, + + "Marketplace" : { + "resource" : "MARKETPLACE", + + "show" : function(params){ + OpenNebula.Action.show(params,OpenNebula.Marketplace.resource); + }, + "list" : function(params){ + //Custom list request function, since the contents do not come + //in the same format as the rest of opennebula resources. + var callback = params.success; + var callback_error = params.error; + var timeout = params.timeout || false; + var request = OpenNebula.Helper.request('MARKETPLACE','list'); + + $.ajax({ + url: 'marketplace', + type: 'GET', + data: {timeout: timeout}, + dataType: "json", + success: function(response){ + return callback ? + callback(request, response) : null; + }, + error: function(res){ + return callback_error ? callback_error(request, OpenNebula.Error(res)) : null; + }, + }); + }, + }, } diff --git a/src/sunstone/public/js/plugins/marketplace-tab.js b/src/sunstone/public/js/plugins/marketplace-tab.js index 64f92a5fb8..716eb9d44a 100644 --- a/src/sunstone/public/js/plugins/marketplace-tab.js +++ b/src/sunstone/public/js/plugins/marketplace-tab.js @@ -17,102 +17,61 @@ /* Marketpplace tab plugin */ var dataTable_marketplace; -/* - * fnReloadAjax: re-read the Ajax source and update the table - */ - -$.fn.dataTableExt.oApi.fnReloadAjax = function ( oSettings, sNewSource, fnCallback, bStandingRedraw ) -{ - if ( typeof sNewSource != 'undefined' && sNewSource != null ) - { - oSettings.sAjaxSource = sNewSource; - } - this.oApi._fnProcessingDisplay( oSettings, true ); - var that = this; - var iStart = oSettings._iDisplayStart; - var aData = []; - - this.oApi._fnServerParams( oSettings, aData ); - - oSettings.fnServerData( oSettings.sAjaxSource, aData, function(json) { - /* Clear the old information from the table */ - that.oApi._fnClearTable( oSettings ); - - /* Got the data - add it to the table */ - var aData = (oSettings.sAjaxDataProp !== "") ? - that.oApi._fnGetObjectDataFn( oSettings.sAjaxDataProp )( json ) : json; - - for ( var i=0 ; iMD5=' + + md5 + ''; + $("#custom_var_image_box",$create_image_dialog).append(option); + } + + var sha1 = response['files'][0]['checksum']['sha1'] + if ( sha1 ) { + option = ''; + $("#custom_var_image_box",$create_image_dialog).append(option); + } + + popUpCreateImageDialog(); + }, + error: onError + }, + "Marketplace.showinfo" : { type: "single", - call: function () { - var app_id = getSelectedNodes(dataTable_marketplace)[0]; - - $.ajax({ - url: "/marketplace/" + app_id, - type: "GET", - dataType: "json", - success: function(response){ - document.getElementById("img_name").value = response['name']; - document.getElementById("img_path").value = response['links']['download']['href']; - - $("#custom_var_image_box",$create_image_dialog).empty(); - - var md5 = response['files'][0]['checksum']['md5'] - if ( md5 ) { - option = ''; - $("#custom_var_image_box",$create_image_dialog).append(option); - } - - var sha1 = response['files'][0]['checksum']['sha1'] - if ( sha1 ) { - option = ''; - $("#custom_var_image_box",$create_image_dialog).append(option); - } - - popUpCreateImageDialog(); - }, - error: function(response) - { - return onError(null, OpenNebula.Error(response)); - } - }); - } + call: OpenNebula.Marketplace.show, + callback: updateMarketInfo, + error: onError } } @@ -175,6 +134,9 @@ var marketplace_info_panel = { Sunstone.addInfoPanel("marketplace_info_panel", marketplace_info_panel); +function marketplaceElements(){ + return getSelectedNodes(dataTable_marketplace); +} function updateMarketInfo(request,app){ var info_tab = { @@ -241,6 +203,8 @@ function infoListenerMarket(dataTable){ var count = $('tbody .check_item:checked', dataTable).length; + //If ctrl is pressed we check the column instead of + //doing showinfo() if (e.ctrlKey || count >= 1){ $('.check_item',this).trigger('click'); return false; @@ -248,19 +212,7 @@ function infoListenerMarket(dataTable){ popDialogLoading(); - $.ajax({ - url: "/marketplace/" + id, - type: "GET", - dataType: "json", - success: function(response){ - return updateMarketInfo(null, response); - }, - error: function(response) - { - return onError(null, OpenNebula.Error(response)); - } - }); - + Sunstone.runAction('Marketplace.showinfo',id); return false; }); } @@ -288,20 +240,23 @@ $(document).ready(function(){ "bSortClasses": false, "sPaginationType": "full_numbers", "sDom" : '<"H"lfrC>t<"F"ip>', - "sAjaxSource": "/marketplace", - "sAjaxDataProp": "appliances", "bAutoWidth":false, "aoColumns": [ { "bSortable": false, "fnRender": function ( o, val ) { - return '' - } }, - { "mDataProp": "_id.$oid", "bVisible": false }, + return '' + }, + "sWidth" : "60px" + }, + { "mDataProp": "_id.$oid", "bVisible": false, "sWidth" : "200px" }, { "mDataProp": "name" }, { "mDataProp": "publisher" }, - { "mDataProp": "files.0.hypervisor"}, - { "mDataProp": "files.0.os-arch"}, - { "mDataProp": "files.0.format"}, + { "mDataProp": "files.0.hypervisor", "sWidth" : "100px"}, + { "mDataProp": "files.0.os-arch", "sWidth" : "100px"}, + { "mDataProp": "files.0.format", "sWidth" : "100px"}, { "mDataProp": "tags", "bVisible": false} ], "oLanguage": (datatable_lang != "") ? @@ -311,9 +266,10 @@ $(document).ready(function(){ }); - initCheckAllBoxes(dataTable_marketplace); tableCheckboxesListener(dataTable_marketplace); onlyOneCheckboxListener(dataTable_marketplace); infoListenerMarket(dataTable_marketplace); + + Sunstone.runAction('Marketplace.list'); }); \ No newline at end of file From 309afa466fabdc591b98fcb10a946439e8a40f66 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 26 Jun 2012 15:16:42 +0200 Subject: [PATCH 03/24] Bug #1314: Increase menu size in self-service so all menu items stay in one line (problem with French) (cherry picked from commit 500155937babf99db4f30c822c0cc6214546ef1b) --- src/cloud/occi/lib/ui/public/js/layout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cloud/occi/lib/ui/public/js/layout.js b/src/cloud/occi/lib/ui/public/js/layout.js index 62bad60e5e..6a9534d719 100644 --- a/src/cloud/occi/lib/ui/public/js/layout.js +++ b/src/cloud/occi/lib/ui/public/js/layout.js @@ -133,7 +133,7 @@ $(document).ready(function () { applyDefaultStyles: false , center__paneSelector: ".outer-center" , west__paneSelector: ".outer-west" - , west__size: 160 + , west__size: 181 , north__size: 26 , south__size: 26 , spacing_open: 0 // ALL panes From d02e1a0e2e4d419da5e497489eb53e7b9fc67a9d Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Tue, 26 Jun 2012 15:18:20 +0200 Subject: [PATCH 04/24] Bug #1314: Fix scrollbar in footer in Chrome browser. Seems a webkit issue. Setting overflow:visible in the footer div seems to be good for FF/Chrome (cherry picked from commit d1e5d48d0c0f04520c957a8b1f4a1b4844ae82ed) --- src/cloud/occi/lib/ui/views/index.erb | 2 +- src/ozones/Server/templates/index.html | 2 +- src/sunstone/views/index.erb | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cloud/occi/lib/ui/views/index.erb b/src/cloud/occi/lib/ui/views/index.erb index 9baeb5f9b4..7e7eeca8d8 100644 --- a/src/cloud/occi/lib/ui/views/index.erb +++ b/src/cloud/occi/lib/ui/views/index.erb @@ -75,7 +75,7 @@ --> - - -'); @@ -1730,7 +1595,6 @@ $(document).ready(function(){ setupCreateVMDialog(); setupVMTemplateUpdateDialog(); - setupSaveasDialog(); setVMAutorefresh(); setupVNC(); hotpluggingOps(); From 8c792cc0ffede47301b11810afa65c19e996d394 Mon Sep 17 00:00:00 2001 From: Hector Sanjuan Date: Wed, 27 Jun 2012 17:32:32 +0200 Subject: [PATCH 11/24] Feature #1288: Sunstone: Add VM quota information to users and groups tables, just as in CLI (cherry picked from commit 88b86d0ab0aeecbdc7b8d25bde6b736ba7538c08) --- src/sunstone/public/js/plugins/groups-tab.js | 23 +++++++++++++++++--- src/sunstone/public/js/plugins/users-tab.js | 23 +++++++++++++++++--- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/sunstone/public/js/plugins/groups-tab.js b/src/sunstone/public/js/plugins/groups-tab.js index 7078915440..4968358b6d 100644 --- a/src/sunstone/public/js/plugins/groups-tab.js +++ b/src/sunstone/public/js/plugins/groups-tab.js @@ -31,6 +31,9 @@ var groups_tab_content = '\ '+tr("ID")+'\ '+tr("Name")+'\ '+tr("Users")+'\ + '+tr("VMs")+'\ + '+tr("Memory used")+'\ + '+tr("CPU used")+'\ \ \ \ @@ -293,11 +296,25 @@ function groupElementArray(group_json){ users_str=getUserName(group.USERS.ID); }; + var vms = "-"; + var memory = "-"; + var cpu = "-"; + + if (!$.isEmptyObject(group.VM_QUOTA)){ + vms = group.VM_QUOTA.VM.VMS_USED; + memory = group.VM_QUOTA.VM.MEMORY_USED; + cpu = group.VM_QUOTA.VM.CPU_USED; + } + return [ '', group.ID, group.NAME, - users_str ]; + users_str, + vms, + memory, + cpu + ]; } function updateGroupSelect(){ @@ -405,7 +422,7 @@ $(document).ready(function(){ "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, - { "sWidth": "35px", "aTargets": [1] } + { "sWidth": "35px", "aTargets": [1,4,5,6] } ], "oLanguage": (datatable_lang != "") ? { @@ -416,7 +433,7 @@ $(document).ready(function(){ dataTable_groups.fnClearTable(); addElement([ spinner, - '','',''],dataTable_groups); + '','','','','',''],dataTable_groups); Sunstone.runAction("Group.list"); setupCreateGroupDialog(); diff --git a/src/sunstone/public/js/plugins/users-tab.js b/src/sunstone/public/js/plugins/users-tab.js index 1884ed5b46..93e634e809 100644 --- a/src/sunstone/public/js/plugins/users-tab.js +++ b/src/sunstone/public/js/plugins/users-tab.js @@ -34,6 +34,9 @@ var users_tab_content = '\ '+tr("Name")+'\ '+tr("Group")+'\ '+tr("Authentication driver")+'\ + '+tr("VMs")+'\ + '+tr("Memory used")+'\ + '+tr("CPU used")+'\ '+tr("Group ID")+'\ \ \ @@ -490,12 +493,26 @@ function userElements(){ function userElementArray(user_json){ var user = user_json.USER; + var vms = "-"; + var memory = "-"; + var cpu = "-"; + + if (!$.isEmptyObject(user.VM_QUOTA)){ + vms = user.VM_QUOTA.VM.VMS_USED; + memory = user.VM_QUOTA.VM.MEMORY_USED; + cpu = user.VM_QUOTA.VM.CPU_USED; + } + + return [ '', user.ID, user.NAME, user.GNAME, user.AUTH_DRIVER, + vms, + memory, + cpu, user.GID ] }; @@ -722,9 +739,9 @@ $(document).ready(function(){ "aoColumnDefs": [ { "bSortable": false, "aTargets": ["check"] }, { "sWidth": "60px", "aTargets": [0] }, - { "sWidth": "35px", "aTargets": [1,5] }, + { "sWidth": "35px", "aTargets": [1,5,6,7,8] }, { "sWidth": "150px", "aTargets": [4] }, - { "bVisible": false, "aTargets": [5]} + { "bVisible": false, "aTargets": [8]} ], "oLanguage": (datatable_lang != "") ? { @@ -734,7 +751,7 @@ $(document).ready(function(){ dataTable_users.fnClearTable(); addElement([ spinner, - '','','','',''],dataTable_users); + '','','','','','','',''],dataTable_users); Sunstone.runAction("User.list"); From 9d8ccd61c81ec706d4b8fa6d6ba68f19738e357d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Wed, 27 Jun 2012 18:50:19 +0200 Subject: [PATCH 12/24] Bug #1316: Clean files when a stopped VM is deleted. Previous commit:dbefe6f only worked with shared DS --- include/DispatchManager.h | 7 ++++ include/TransferManager.h | 19 +++++++++- src/dm/DispatchManagerActions.cc | 65 ++++++++++++++++++++------------ src/tm/TransferManager.cc | 62 ++++++++++++++++++++++-------- 4 files changed, 112 insertions(+), 41 deletions(-) diff --git a/include/DispatchManager.h b/include/DispatchManager.h index 9ac342c59d..54631501ff 100644 --- a/include/DispatchManager.h +++ b/include/DispatchManager.h @@ -302,6 +302,13 @@ private: const string & action, void * arg); + /** + * Called from finalize(). Releases the images and networks acquired by this + * vm, and unlocks it. + * @param vm the VM + */ + void finalize_cleanup(VirtualMachine * vm); + //-------------------------------------------------------------------------- // DM Actions associated with a VM state transition //-------------------------------------------------------------------------- diff --git a/include/TransferManager.h b/include/TransferManager.h index 1b33323690..6b08f3d73b 100644 --- a/include/TransferManager.h +++ b/include/TransferManager.h @@ -53,6 +53,7 @@ public: EPILOG_STOP, EPILOG_DELETE, EPILOG_DELETE_PREVIOUS, + EPILOG_DELETE_STOP, CHECKPOINT, DRIVER_CANCEL, FINALIZE @@ -239,7 +240,23 @@ private: /** * This function starts the epilog_delete sequence */ - void epilog_delete_action(int vid); + void epilog_delete_action(int vid) + { + epilog_delete_action(false, vid); + } + + /** + * This function starts the epilog_delete_stop sequence on the local host + */ + void epilog_delete_stop_action(int vid) + { + epilog_delete_action(true, vid); + } + + /** + * This function starts the epilog_delete sequence + */ + void epilog_delete_action(bool local, int vid); /** * This function starts the epilog_delete sequence on the previous host diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc index 4b5a1dd6bc..7484b1bb92 100644 --- a/src/dm/DispatchManagerActions.cc +++ b/src/dm/DispatchManagerActions.cc @@ -680,15 +680,43 @@ error: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +void DispatchManager::finalize_cleanup(VirtualMachine * vm) +{ + Template * tmpl; + + int uid; + int gid; + + vm->release_network_leases(); + vm->release_disk_images(); + + vm->set_exit_time(time(0)); + + vm->set_state(VirtualMachine::LCM_INIT); + vm->set_state(VirtualMachine::DONE); + vmpool->update(vm); + + vm->log("DiM", Log::INFO, "New VM state is DONE."); + + uid = vm->get_uid(); + gid = vm->get_gid(); + tmpl = vm->clone_template(); + + vm->unlock(); + + Quotas::vm_del(uid, gid, tmpl); + + delete tmpl; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + int DispatchManager::finalize( int vid) { VirtualMachine * vm; ostringstream oss; - Template * tmpl; - - int uid; - int gid; VirtualMachine::VmState state; @@ -711,33 +739,20 @@ int DispatchManager::finalize( switch (state) { case VirtualMachine::SUSPENDED: - case VirtualMachine::STOPPED: case VirtualMachine::FAILED: tm->trigger(TransferManager::EPILOG_DELETE,vid); + finalize_cleanup(vm); + break; + + case VirtualMachine::STOPPED: + tm->trigger(TransferManager::EPILOG_DELETE_STOP,vid); + finalize_cleanup(vm); + break; case VirtualMachine::INIT: case VirtualMachine::PENDING: case VirtualMachine::HOLD: - vm->release_network_leases(); - vm->release_disk_images(); - - vm->set_exit_time(time(0)); - - vm->set_state(VirtualMachine::LCM_INIT); - vm->set_state(VirtualMachine::DONE); - vmpool->update(vm); - - vm->log("DiM", Log::INFO, "New VM state is DONE."); - - uid = vm->get_uid(); - gid = vm->get_gid(); - tmpl = vm->clone_template(); - - vm->unlock(); - - Quotas::vm_del(uid, gid, tmpl); - - delete tmpl; + finalize_cleanup(vm); break; case VirtualMachine::ACTIVE: diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 2a40fb38ba..1862dbaf3b 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -107,6 +107,10 @@ void TransferManager::trigger(Actions action, int _vid) aname = "EPILOG_DELETE"; break; + case EPILOG_DELETE_STOP: + aname = "EPILOG_DELETE_STOP"; + break; + case EPILOG_DELETE_PREVIOUS: aname = "EPILOG_DELETE_PREVIOUS"; break; @@ -171,6 +175,10 @@ void TransferManager::do_action(const string &action, void * arg) { epilog_delete_action(vid); } + else if (action == "EPILOG_DELETE_STOP") + { + epilog_delete_stop_action(vid); + } else if (action == "EPILOG_DELETE_PREVIOUS") { epilog_delete_previous_action(vid); @@ -1033,11 +1041,10 @@ error_common: return; } - /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -void TransferManager::epilog_delete_action(int vid) +void TransferManager::epilog_delete_action(bool local, int vid) { ofstream xfr; ostringstream os; @@ -1113,21 +1120,46 @@ void TransferManager::epilog_delete_action(int vid) continue; } - //DELETE tm_mad host:remote_system_dir/disk.i vmid dsid - xfr << "DELETE " - << tm_mad << " " - << vm->get_hostname() << ":" - << vm->get_remote_system_dir() << "/disk." << disk_id << " " - << vm->get_oid() << " " - << ds_id << endl; + if ( local ) + { + //DELETE tm_mad fe:system_dir/disk.i vmid dsid + xfr << "DELETE " + << tm_mad << " " + << nd.get_nebula_hostname() << ":" + << vm->get_system_dir() << "/disk." << disk_id << " " + << vm->get_oid() << " " + << ds_id << endl; + } + else + { + //DELETE tm_mad host:remote_system_dir/disk.i vmid dsid + xfr << "DELETE " + << tm_mad << " " + << vm->get_hostname() << ":" + << vm->get_remote_system_dir() << "/disk." << disk_id << " " + << vm->get_oid() << " " + << ds_id << endl; + } } - //DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0) - xfr << "DELETE " - << system_tm_mad << " " - << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " " - << vm->get_oid() << " " - << "0"; + if ( local ) + { + //DELETE system_tm_mad fe:system_dir vmid dsid(=0) + xfr << "DELETE " + << system_tm_mad << " " + << nd.get_nebula_hostname() <<":"<< vm->get_system_dir() << " " + << vm->get_oid() << " " + << "0"; + } + else + { + //DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0) + xfr << "DELETE " + << system_tm_mad << " " + << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " " + << vm->get_oid() << " " + << "0"; + } xfr.close(); From c1d8dc72a4b90a290fa74903d4569ac33837aaf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 28 Jun 2012 12:49:20 +0200 Subject: [PATCH 13/24] Bug #1322: Do not create objects with negative ID --- src/pool/PoolSQL.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/pool/PoolSQL.cc b/src/pool/PoolSQL.cc index 1afb6775cb..15ff33d1b1 100644 --- a/src/pool/PoolSQL.cc +++ b/src/pool/PoolSQL.cc @@ -168,6 +168,12 @@ PoolObjectSQL * PoolSQL::get( PoolObjectSQL * objectsql; int rc; + if ( oid < 0 ) + { + objectsql = 0; + return objectsql; + } + lock(); index = pool.find(oid); @@ -212,6 +218,7 @@ PoolObjectSQL * PoolSQL::get( unlock(); + objectsql = 0; return 0; } From 1130e37a2e11ac939ef8a8645df7ce33b119f017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 28 Jun 2012 13:21:19 +0200 Subject: [PATCH 14/24] Bug #1322: Check if user quota rollback is needed; polish quota error messages --- include/Request.h | 31 +++++++++++++++--- src/rm/Request.cc | 61 ++++++++++++++++++++++++++++------- src/rm/RequestManagerChown.cc | 10 ++++-- src/um/Quota.cc | 2 +- 4 files changed, 85 insertions(+), 19 deletions(-) diff --git a/include/Request.h b/include/Request.h index 841e39f71c..07129634ee 100644 --- a/include/Request.h +++ b/include/Request.h @@ -160,16 +160,39 @@ protected: /** * Performs a basic quota check for this request using the uid/gid - * from the request. Usage counters are updated for the user/group. + * from the request. Usage counters are updated for the user/group. + * On case of error, the failure_response return values are set + * * @param tmpl describing the object * @param object type of the object * @param att the specific request attributes * * @return true if the user is authorized. */ - bool quota_authorization(Template * tmpl, - Quotas::QuotaType qtype, - RequestAttributes& att); + bool quota_authorization( + Template * tmpl, + Quotas::QuotaType qtype, + RequestAttributes& att); + + /** + * Performs a basic quota check for this request using the uid/gid + * from the request. Usage counters are updated for the user/group. + * On case of error, the failure_response return values is not set, instead + * the error reason is returned in error_str + * + * @param tmpl describing the object + * @param object type of the object + * @param att the specific request attributes + * + * @param error_str Error reason, if any + * @return true if the user is authorized. + */ + bool quota_authorization( + Template * tmpl, + Quotas::QuotaType qtype, + RequestAttributes& att, + string& error_str); + /** * Performs rollback on usage counters for a previous quota check operation * for the request. diff --git a/src/rm/Request.cc b/src/rm/Request.cc index a9a27a2f36..0a9f4d3450 100644 --- a/src/rm/Request.cc +++ b/src/rm/Request.cc @@ -137,6 +137,15 @@ bool Request::user_quota_authorization (Template * tmpl, { upool->update(user); } + else + { + ostringstream oss; + + oss << object_name(PoolObjectSQL::USER) << " [" << att.uid << "] " + << error_str; + + error_str = oss.str(); + } user->unlock(); @@ -170,6 +179,15 @@ bool Request::group_quota_authorization (Template * tmpl, { gpool->update(group); } + else + { + ostringstream oss; + + oss << object_name(PoolObjectSQL::GROUP) << " [" << att.gid << "] " + << error_str; + + error_str = oss.str(); + } group->unlock(); @@ -229,35 +247,54 @@ void Request::group_quota_rollback(Template * tmpl, /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -bool Request::quota_authorization(Template * tmpl, +bool Request::quota_authorization(Template * tmpl, Quotas::QuotaType qtype, RequestAttributes& att) { string error_str; + bool auth = quota_authorization(tmpl, qtype, att, error_str); + + if ( auth == false ) + { + failure_response(AUTHORIZATION, + request_error(error_str, ""), + att); + } + + return auth; +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +bool Request::quota_authorization( + Template * tmpl, + Quotas::QuotaType qtype, + RequestAttributes& att, + string& error_str) +{ // uid/gid == -1 means do not update user/group - if ( att.uid != UserPool::ONEADMIN_ID && att.uid != -1) + bool do_user_quota = att.uid != UserPool::ONEADMIN_ID && att.uid != -1; + bool do_group_quota = att.gid != GroupPool::ONEADMIN_ID && att.gid != -1; + + if ( do_user_quota ) { if ( user_quota_authorization(tmpl, qtype, att, error_str) == false ) { - failure_response(AUTHORIZATION, - authorization_error(error_str, att), - att); - return false; } } - if ( att.gid != GroupPool::ONEADMIN_ID && att.gid != -1) + if ( do_group_quota ) { if ( group_quota_authorization(tmpl, qtype, att, error_str) == false ) { - user_quota_rollback(tmpl, qtype, att); - - failure_response(AUTHORIZATION, - authorization_error(error_str, att), - att); + if ( do_user_quota ) + { + user_quota_rollback(tmpl, qtype, att); + } return false; } diff --git a/src/rm/RequestManagerChown.cc b/src/rm/RequestManagerChown.cc index 0714d820c3..3ac2025f39 100644 --- a/src/rm/RequestManagerChown.cc +++ b/src/rm/RequestManagerChown.cc @@ -37,6 +37,8 @@ PoolObjectSQL * RequestManagerChown::get_and_quota( PoolObjectSQL * object; Quotas::QuotaType qtype; + string error_str; + object = pool->get(oid,true); if ( object == 0 ) @@ -86,8 +88,12 @@ PoolObjectSQL * RequestManagerChown::get_and_quota( RequestAttributes att_new(new_uid, new_gid, att); RequestAttributes att_old(old_uid, old_gid, att); - if ( quota_authorization(tmpl, qtype, att_new) == false ) + if ( quota_authorization(tmpl, qtype, att_new, error_str) == false ) { + failure_response(AUTHORIZATION, + request_error(error_str, ""), + att); + delete tmpl; return 0; } @@ -100,7 +106,7 @@ PoolObjectSQL * RequestManagerChown::get_and_quota( { quota_rollback(tmpl, qtype, att_new); - quota_authorization(tmpl, qtype, att_old); + quota_authorization(tmpl, qtype, att_old, error_str); failure_response(NO_EXISTS, get_error(object_name(auth_object), oid), diff --git a/src/um/Quota.cc b/src/um/Quota.cc index 03fc1435b2..472e25dcf4 100644 --- a/src/um/Quota.cc +++ b/src/um/Quota.cc @@ -230,7 +230,7 @@ bool Quota::check_quota(const string& qid, { ostringstream oss; - oss << "Limit of " << limit << " reached for " << metrics[i] + oss << "limit of " << limit << " reached for " << metrics[i] << " quota in " << template_name; if ( !qid.empty() ) From d5b40785f5a2e868675067d0aa9ce70d683e8156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 28 Jun 2012 15:32:52 +0200 Subject: [PATCH 15/24] Bug #1306: Add tm_mad to History elements --- include/History.h | 2 ++ include/RequestManagerVirtualMachine.h | 3 ++- include/VirtualMachine.h | 23 ++++++++++++++++++++++- src/rm/RequestManagerVirtualMachine.cc | 15 ++++++++++----- src/vm/History.cc | 8 ++++++++ src/vm/VirtualMachine.cc | 6 +++++- 6 files changed, 49 insertions(+), 8 deletions(-) diff --git a/include/History.h b/include/History.h index 952320e62c..7852cfed46 100644 --- a/include/History.h +++ b/include/History.h @@ -46,6 +46,7 @@ public: const string& hostname, const string& vmm, const string& vnm, + const string& tmm, const string& vm_info); ~History(){}; @@ -89,6 +90,7 @@ private: string vmm_mad_name; string vnm_mad_name; + string tm_mad_name; time_t stime; time_t etime; diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index 10b415352d..f4c8866cac 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -57,13 +57,14 @@ protected: AuthRequest::Operation op); int get_host_information(int hid, string& name, string& vmm, string& vnm, - RequestAttributes& att, PoolObjectAuth& host_perms); + string& tm, RequestAttributes& att, PoolObjectAuth& host_perms); int add_history(VirtualMachine * vm, int hid, const string& hostname, const string& vmm_mad, const string& vnm_mad, + const string& tm_mad, RequestAttributes& att); VirtualMachine * get_vm(int id, RequestAttributes& att); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 7a16a92e3a..36eeacea67 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -242,7 +242,8 @@ public: int hid, const string& hostname, const string& vmm_mad, - const string& vnm_mad); + const string& vnm_mad, + const string& tm_mad); /** * Duplicates the last history record. Only the host related fields are @@ -318,6 +319,26 @@ public: return previous_history->vnm_mad_name; }; + /** + * Returns the TM driver name for the current host. The hasHistory() + * function MUST be called before this one. + * @return the TM mad name + */ + const string & get_tm_mad() const + { + return history->tm_mad_name; + }; + + /** + * Returns the TM driver name for the previous host. The + * hasPreviousHistory() function MUST be called before this one. + * @return the TM mad name + */ + const string & get_previous_tm_mad() const + { + return previous_history->tm_mad_name; + }; + /** * Returns the transfer filename. The transfer file is in the form: * $ONE_LOCATION/var/$VM_ID/transfer.$SEQ diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index d4d7e7cd39..67e14dc50b 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -99,6 +99,7 @@ int RequestManagerVirtualMachine::get_host_information(int hid, string& name, string& vmm, string& vnm, + string& tm, RequestAttributes& att, PoolObjectAuth& host_perms) { @@ -121,6 +122,7 @@ int RequestManagerVirtualMachine::get_host_information(int hid, name = host->get_name(); vmm = host->get_vmm_mad(); vnm = host->get_vnm_mad(); + tm = ""; // TODO host->get_cluster_id, get DS from Cluster, get TM from DS host->get_permissions(host_perms); @@ -156,6 +158,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, const string& hostname, const string& vmm_mad, const string& vnm_mad, + const string& tm_mad, RequestAttributes& att) { string vmdir; @@ -163,7 +166,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, VirtualMachinePool * vmpool = static_cast(pool); - vm->add_history(hid,hostname,vmm_mad,vnm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad,tm_mad); rc = vmpool->update_history(vm); @@ -308,13 +311,14 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, string hostname; string vmm_mad; string vnm_mad; + string tm_mad; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0) + if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad,att, host_perms) != 0) { return; } @@ -341,7 +345,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0) { vm->unlock(); return; @@ -369,6 +373,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList string hostname; string vmm_mad; string vnm_mad; + string tm_mad; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); @@ -376,7 +381,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,att, host_perms) != 0) + if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad,att, host_perms) != 0) { return; } @@ -405,7 +410,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0) { vm->unlock(); return; diff --git a/src/vm/History.cc b/src/vm/History.cc index 4d7580aba9..415c990060 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -44,6 +44,7 @@ History::History( hid(-1), vmm_mad_name(""), vnm_mad_name(""), + tm_mad_name(""), stime(0), etime(0), prolog_stime(0), @@ -64,6 +65,7 @@ History::History( const string& _hostname, const string& _vmm, const string& _vnm, + const string& _tmm, const string& _vm_info): oid(_oid), seq(_seq), @@ -71,6 +73,7 @@ History::History( hid(_hid), vmm_mad_name(_vmm), vnm_mad_name(_vnm), + tm_mad_name(_tmm), stime(0), etime(0), prolog_stime(0), @@ -292,6 +295,7 @@ string& History::to_xml(string& xml, bool database) const "" << etime << "" << "" << vmm_mad_name << ""<< "" << vnm_mad_name << ""<< + "" << tm_mad_name << "" << "" << prolog_stime << ""<< "" << prolog_etime << ""<< "" << running_stime << ""<< @@ -328,6 +332,10 @@ int History::rebuild_attributes() rc += xpath(etime , "/HISTORY/ETIME", 0); rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); + + // TODO: add TMMAD element in onedb migrator + rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); + rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); rc += xpath(running_stime , "/HISTORY/RSTIME", 0); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 54fa086a92..46ec12eb05 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -826,7 +826,8 @@ void VirtualMachine::add_history( int hid, const string& hostname, const string& vmm_mad, - const string& vnm_mad) + const string& vnm_mad, + const string& tm_mad) { ostringstream os; int seq; @@ -851,6 +852,7 @@ void VirtualMachine::add_history( hostname, vmm_mad, vnm_mad, + tm_mad, vm_xml); history_records.push_back(history); @@ -877,6 +879,7 @@ void VirtualMachine::cp_history() history->hostname, history->vmm_mad_name, history->vnm_mad_name, + history->tm_mad_name, vm_xml); previous_history = history; @@ -906,6 +909,7 @@ void VirtualMachine::cp_previous_history() previous_history->hostname, previous_history->vmm_mad_name, previous_history->vnm_mad_name, + previous_history->tm_mad_name, vm_xml); previous_history = history; From ffc99eea2fd0afbb9113a4bd482bdd9f63eda7d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 28 Jun 2012 16:45:00 +0200 Subject: [PATCH 16/24] Bug #1306: Use the tm_mad stored in the history, instead of the system_ds tm_mad --- include/Nebula.h | 24 --- src/rm/RequestManagerVirtualMachine.cc | 41 ++++- src/tm/TransferManager.cc | 222 +++++++++++++------------ src/vmm/VirtualMachineManager.cc | 10 +- 4 files changed, 162 insertions(+), 135 deletions(-) diff --git a/include/Nebula.h b/include/Nebula.h index 1bab2d21b6..a3aa35b781 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -243,30 +243,6 @@ public: return ds_location; }; - /** - * Returns the Transfer Manager for the system datastore - * @return the tm name. - */ - string get_system_ds_tm_mad() - { - Datastore * ds; - string tm_mad = ""; - - ds = dspool->get(DatastorePool::SYSTEM_DS_ID, true); - - if ( ds == 0 ) - { - NebulaLog::log("DaS", Log::ERROR, "Can not get system datastore"); - return tm_mad; - } - - tm_mad = ds->get_tm_mad(); - - ds->unlock(); - - return tm_mad; - }; - /** * Returns the path of the log file for a VM, depending where OpenNebula is * installed, diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 67e14dc50b..90ec095ced 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -106,7 +106,12 @@ int RequestManagerVirtualMachine::get_host_information(int hid, Nebula& nd = Nebula::instance(); HostPool * hpool = nd.get_hpool(); - Host * host; + Host * host; + Cluster * cluster; + Datastore * ds; + + int cluster_id; + int ds_id; host = hpool->get(hid,true); @@ -122,12 +127,44 @@ int RequestManagerVirtualMachine::get_host_information(int hid, name = host->get_name(); vmm = host->get_vmm_mad(); vnm = host->get_vnm_mad(); - tm = ""; // TODO host->get_cluster_id, get DS from Cluster, get TM from DS host->get_permissions(host_perms); + cluster_id = host->get_cluster_id(); + host->unlock(); + cluster = nd.get_clpool()->get(cluster_id, true); + + if ( cluster == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); + + return -1; + } + + // TODO: ds_id = cluster->get_datastore() + ds_id = DatastorePool::SYSTEM_DS_ID; + + cluster->unlock(); + + ds = nd.get_dspool()->get(ds_id, true); + + if ( ds == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::DATASTORE),ds_id), + att); + + return -1; + } + + tm = ds->get_tm_mad(); + + ds->unlock(); + return 0; } diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 1862dbaf3b..680a5f894f 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -212,7 +212,7 @@ void TransferManager::do_action(const string &action, void * arg) int TransferManager::prolog_transfer_command( VirtualMachine * vm, const VectorAttribute * disk, - string& system_tm_mad, + string& vm_tm_mad, string& opennebula_hostname, ostream& xfr, ostringstream& os) @@ -248,7 +248,7 @@ int TransferManager::prolog_transfer_command( //MKSWAP tm_mad size host:remote_system_dir/disk.i vmid dsid(=0) xfr << "MKSWAP " - << system_tm_mad << " " + << vm_tm_mad << " " << size << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << "/disk." << disk_index << " " @@ -273,7 +273,7 @@ int TransferManager::prolog_transfer_command( //MKIMAGE tm_mad size format host:remote_system_dir/disk.i vmid dsid(=0) xfr << "MKIMAGE " - << system_tm_mad << " " + << vm_tm_mad << " " << size << " " << format << " " << vm->get_hostname() << ":" @@ -356,7 +356,7 @@ void TransferManager::prolog_action(int vid) const VectorAttribute * disk; string files; - string system_tm_mad; + string vm_tm_mad; string opennebula_hostname; int rc; string error_str; @@ -374,17 +374,6 @@ void TransferManager::prolog_action(int vid) // ------------------------------------------------------------------------- // Setup & Transfer script // ------------------------------------------------------------------------- - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "prolog, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -397,6 +386,14 @@ void TransferManager::prolog_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".prolog"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -423,7 +420,7 @@ void TransferManager::prolog_action(int vid) rc = prolog_transfer_command(vm, disk, - system_tm_mad, + vm_tm_mad, opennebula_hostname, xfr, os); @@ -447,7 +444,7 @@ void TransferManager::prolog_action(int vid) { //CONTEXT tm_mad files hostname:remote_system_dir/disk.i vmid dsid(=0) xfr << "CONTEXT " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_context_file() << " "; if (!files.empty()) @@ -472,6 +469,11 @@ error_history: os << "VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "prolog, error getting drivers."; + goto error_common; + error_file: os << "could not open file: " << xfr_name; goto error_common; @@ -505,7 +507,7 @@ void TransferManager::prolog_migr_action(int vid) const VectorAttribute * disk; string tm_mad; - string system_tm_mad; + string vm_tm_mad; string ds_id; int disk_id; @@ -520,17 +522,6 @@ void TransferManager::prolog_migr_action(int vid) // ------------------------------------------------------------------------- // Setup & Transfer script // ------------------------------------------------------------------------- - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "prolog_migr, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -538,11 +529,19 @@ void TransferManager::prolog_migr_action(int vid) return; } - if (!vm->hasHistory()) + if (!vm->hasHistory() || !vm->hasPreviousHistory()) { goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".migrate"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -588,7 +587,7 @@ void TransferManager::prolog_migr_action(int vid) //MV tm_mad prev_host:remote_system_dir host:remote_system_dir VMID 0 xfr << "MV " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_hostname() << ":" @@ -608,6 +607,11 @@ error_history: os << "prolog_migr, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "prolog_migr, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "prolog_migr, could not open file: " << xfr_name; @@ -632,7 +636,7 @@ void TransferManager::prolog_resume_action(int vid) const VectorAttribute * disk; string tm_mad; - string system_tm_mad; + string vm_tm_mad; string ds_id; int disk_id; @@ -647,17 +651,6 @@ void TransferManager::prolog_resume_action(int vid) // ------------------------------------------------------------------------- // Setup & Transfer script // ------------------------------------------------------------------------- - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "prolog_resume, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -670,6 +663,14 @@ void TransferManager::prolog_resume_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".resume"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -714,7 +715,7 @@ void TransferManager::prolog_resume_action(int vid) //MV tm_mad fe:system_dir host:remote_system_dir vmid 0 xfr << "MV " - << system_tm_mad << " " + << vm_tm_mad << " " << nd.get_nebula_hostname() << ":"<< vm->get_system_dir() << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir()<< " " << vm->get_oid() << " " @@ -732,6 +733,11 @@ error_history: os << "prolog_resume, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "prolog_resume, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "prolog_resume, could not open file: " << xfr_name; @@ -821,7 +827,7 @@ void TransferManager::epilog_action(int vid) ofstream xfr; ostringstream os; string xfr_name; - string system_tm_mad; + string vm_tm_mad; string error_str; const VectorAttribute * disk; @@ -837,17 +843,6 @@ void TransferManager::epilog_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -860,6 +855,14 @@ void TransferManager::epilog_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".epilog"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -885,9 +888,9 @@ void TransferManager::epilog_action(int vid) epilog_transfer_command(vm, disk, xfr); } - //DELETE system_tm_mad hostname:remote_system_dir vmid ds_id + //DELETE vm_tm_mad hostname:remote_system_dir vmid ds_id xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_oid() << " " << "0" << endl; @@ -904,6 +907,11 @@ error_history: os << "epilog, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "epilog, could not open file: " << xfr_name; @@ -926,7 +934,7 @@ void TransferManager::epilog_stop_action(int vid) ostringstream os; string xfr_name; string tm_mad; - string system_tm_mad; + string vm_tm_mad; string ds_id; int disk_id; @@ -942,17 +950,6 @@ void TransferManager::epilog_stop_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog_stop, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -965,6 +962,14 @@ void TransferManager::epilog_stop_action(int vid) goto error_history; } + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".stop"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -1007,9 +1012,9 @@ void TransferManager::epilog_stop_action(int vid) << ds_id << endl; } - //MV system_tm_mad hostname:remote_system_dir fe:system_dir + //MV vm_tm_mad hostname:remote_system_dir fe:system_dir xfr << "MV " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << nd.get_nebula_hostname() << ":" << vm->get_system_dir() << " " << vm->get_oid() << " " @@ -1028,6 +1033,11 @@ error_history: os << "epilog_stop, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog_stop, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "epilog_stop, could not open file: " << xfr_name; @@ -1049,7 +1059,7 @@ void TransferManager::epilog_delete_action(bool local, int vid) ofstream xfr; ostringstream os; string xfr_name; - string system_tm_mad; + string vm_tm_mad; string tm_mad; string ds_id; int disk_id; @@ -1066,17 +1076,6 @@ void TransferManager::epilog_delete_action(bool local, int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog_delete, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -1088,7 +1087,15 @@ void TransferManager::epilog_delete_action(bool local, int vid) { goto error_history; } - + + vm_tm_mad = vm->get_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".delete"; xfr.open(xfr_name.c_str(), ios::out | ios::trunc); @@ -1144,18 +1151,18 @@ void TransferManager::epilog_delete_action(bool local, int vid) if ( local ) { - //DELETE system_tm_mad fe:system_dir vmid dsid(=0) + //DELETE vm_tm_mad fe:system_dir vmid dsid(=0) xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << nd.get_nebula_hostname() <<":"<< vm->get_system_dir() << " " << vm->get_oid() << " " << "0"; } else { - //DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0) + //DELETE vm_tm_mad hostname:remote_system_dir vmid dsid(=0) xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " " << vm->get_oid() << " " << "0"; @@ -1173,6 +1180,11 @@ error_history: os << "epilog_delete, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog_delete, error getting drivers."; + goto error_common; + error_file: os.str(""); os << "epilog_delete, could not open file: " << xfr_name; @@ -1196,7 +1208,7 @@ void TransferManager::epilog_delete_previous_action(int vid) ofstream xfr; ostringstream os; string xfr_name; - string system_tm_mad; + string vm_tm_mad; string tm_mad; string ds_id; int disk_id; @@ -1213,17 +1225,6 @@ void TransferManager::epilog_delete_previous_action(int vid) // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ - system_tm_mad = nd.get_system_ds_tm_mad(); - tm_md = get(); - - if ( tm_md == 0 || system_tm_mad.empty() ) - { - NebulaLog::log("TM", Log::ERROR, "epilog_delete, error getting drivers."); - (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); - - return; - } - vm = vmpool->get(vid,true); if (vm == 0) @@ -1236,6 +1237,14 @@ void TransferManager::epilog_delete_previous_action(int vid) goto error_history; } + vm_tm_mad = vm->get_previous_tm_mad(); + tm_md = get(); + + if ( tm_md == 0 || vm_tm_mad.empty() ) + { + goto error_drivers; + } + xfr_name = vm->get_transfer_file() + ".delete_prev"; xfr.open(xfr_name.c_str(),ios::out | ios::trunc); @@ -1276,9 +1285,9 @@ void TransferManager::epilog_delete_previous_action(int vid) << ds_id << endl; } - //DELTE system_tm_mad prev_host:remote_system_dir vmid ds_id(=0) + //DELTE vm_tm_mad prev_host:remote_system_dir vmid ds_id(=0) xfr << "DELETE " - << system_tm_mad << " " + << vm_tm_mad << " " << vm->get_previous_hostname() <<":"<< vm->get_remote_system_dir() << " " << vm->get_oid() << " " << "0" << endl; @@ -1295,9 +1304,14 @@ error_history: os << "epilog_delete_previous, VM " << vid << " has no history"; goto error_common; +error_drivers: + os.str(""); + os << "epilog_delete_previous, error getting drivers."; + goto error_common; + error_file: os.str(""); - os << "epilog_delete, could not open file: " << xfr_name; + os << "epilog_delete_previous, could not open file: " << xfr_name; os << ". You may need to manually clean " << vm->get_previous_hostname() << ":" << vm->get_remote_system_dir(); goto error_common; diff --git a/src/vmm/VirtualMachineManager.cc b/src/vmm/VirtualMachineManager.cc index ecd651acc1..1565dabfd0 100644 --- a/src/vmm/VirtualMachineManager.cc +++ b/src/vmm/VirtualMachineManager.cc @@ -1313,7 +1313,7 @@ void VirtualMachineManager::attach_action( string vm_tmpl; string* drv_msg; string tm_command; - string system_tm_mad; + string vm_tm_mad; string opennebula_hostname; string prolog_cmd; string disk_path; @@ -1352,13 +1352,13 @@ void VirtualMachineManager::attach_action( goto error_disk; } - system_tm_mad = nd.get_system_ds_tm_mad(); + vm_tm_mad = vm->get_tm_mad(); opennebula_hostname = nd.get_nebula_hostname(); rc = Nebula::instance().get_tm()->prolog_transfer_command( vm, disk, - system_tm_mad, + vm_tm_mad, opennebula_hostname, os, error_os); @@ -1445,7 +1445,7 @@ void VirtualMachineManager::detach_action( string vm_tmpl; string * drv_msg; string tm_command; - string system_tm_mad; + string vm_tm_mad; string opennebula_hostname; string epilog_cmd; string disk_path; @@ -1484,7 +1484,7 @@ void VirtualMachineManager::detach_action( goto error_disk; } - system_tm_mad = nd.get_system_ds_tm_mad(); + vm_tm_mad = vm->get_tm_mad(); opennebula_hostname = nd.get_nebula_hostname(); disk->vector_value("DISK_ID", disk_id); From a6b2c86bfb3129f727a20461cc5b4f8690c1c7c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Thu, 28 Jun 2012 17:51:21 +0200 Subject: [PATCH 17/24] Bug #1306: Add Template contents to Clusters --- include/Cluster.h | 17 +++++--- include/ClusterPool.h | 2 +- include/ClusterTemplate.h | 39 +++++++++++++++++++ include/Datastore.h | 2 +- include/RequestManagerUpdateTemplate.h | 18 +++++++++ src/cli/one_helper/onecluster_helper.rb | 5 +++ src/cli/onecluster | 12 ++++++ src/cluster/Cluster.cc | 38 +++++++++++++++++- src/cluster/ClusterPool.cc | 2 +- .../opennebula/client/cluster/Cluster.java | 25 ++++++++++++ src/oca/ruby/OpenNebula/Cluster.rb | 13 ++++++- src/rm/RequestManager.cc | 2 + 12 files changed, 165 insertions(+), 10 deletions(-) create mode 100644 include/ClusterTemplate.h diff --git a/include/Cluster.h b/include/Cluster.h index d1c10c0760..002328bd05 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -20,6 +20,7 @@ #include "PoolSQL.h" #include "ObjectCollection.h" #include "DatastorePool.h" +#include "ClusterTemplate.h" using namespace std; @@ -184,11 +185,9 @@ private: // Constructor // ************************************************************************* - Cluster(int id, const string& name): - PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), - hosts("HOSTS"), - datastores("DATASTORES"), - vnets("VNETS"){}; + Cluster(int id, + const string& name, + ClusterTemplate* cl_template); virtual ~Cluster(){}; @@ -259,6 +258,14 @@ private: * @return 0 if cluster can be dropped, -1 otherwise */ int check_drop(string& error_msg); + + /** + * Factory method for cluster templates + */ + Template * get_new_template() const + { + return new ClusterTemplate; + } }; #endif /*CLUSTER_H_*/ diff --git a/include/ClusterPool.h b/include/ClusterPool.h index 365dac64e3..35712708ed 100644 --- a/include/ClusterPool.h +++ b/include/ClusterPool.h @@ -151,7 +151,7 @@ private: */ PoolObjectSQL * create() { - return new Cluster(-1,""); + return new Cluster(-1,"",0); }; }; diff --git a/include/ClusterTemplate.h b/include/ClusterTemplate.h new file mode 100644 index 0000000000..b317b2e592 --- /dev/null +++ b/include/ClusterTemplate.h @@ -0,0 +1,39 @@ +/* -------------------------------------------------------------------------- */ +/* 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. */ +/* -------------------------------------------------------------------------- */ + +#ifndef CLUSTER_TEMPLATE_H_ +#define CLUSTER_TEMPLATE_H_ + +#include "Template.h" + +using namespace std; + +/** + * Cluster Template class + */ +class ClusterTemplate : public Template +{ +public: + ClusterTemplate(): + Template(false,'=',"TEMPLATE"){}; + + ~ClusterTemplate(){}; +}; + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + +#endif /*CLUSTER_TEMPLATE_H_*/ diff --git a/include/Datastore.h b/include/Datastore.h index a18408b4df..ceaf552fde 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -203,7 +203,7 @@ private: } /** - * Factory method for virtual network templates + * Factory method for datastore templates */ Template * get_new_template() const { diff --git a/include/RequestManagerUpdateTemplate.h b/include/RequestManagerUpdateTemplate.h index 73880f540e..511f149ce7 100644 --- a/include/RequestManagerUpdateTemplate.h +++ b/include/RequestManagerUpdateTemplate.h @@ -170,6 +170,24 @@ public: ~DocumentUpdateTemplate(){}; }; +/* ------------------------------------------------------------------------- */ +/* ------------------------------------------------------------------------- */ + +class ClusterUpdateTemplate : public RequestManagerUpdateTemplate +{ +public: + ClusterUpdateTemplate(): + RequestManagerUpdateTemplate("ClusterUpdateTemplate", + "Updates a cluster template") + { + Nebula& nd = Nebula::instance(); + pool = nd.get_clpool(); + auth_object = PoolObjectSQL::CLUSTER; + }; + + ~ClusterUpdateTemplate(){}; +}; + /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ diff --git a/src/cli/one_helper/onecluster_helper.rb b/src/cli/one_helper/onecluster_helper.rb index aca9f36d6c..41028cb90a 100644 --- a/src/cli/one_helper/onecluster_helper.rb +++ b/src/cli/one_helper/onecluster_helper.rb @@ -99,6 +99,11 @@ class OneClusterHelper < OpenNebulaHelper::OneHelper puts str % ["NAME", cluster.name] puts + CLIHelper.print_header(str_h1 % "CLUSTER TEMPLATE", false) + puts cluster.template_str + + puts + CLIHelper.print_header("%-15s" % ["HOSTS"]) cluster.host_ids.each do |id| puts "%-15s" % [id] diff --git a/src/cli/onecluster b/src/cli/onecluster index 8cb5ac0dd3..6497e6b34e 100755 --- a/src/cli/onecluster +++ b/src/cli/onecluster @@ -173,4 +173,16 @@ cmd=CommandParser::CmdParser.new(ARGV) do cluster.delvnet(args[1].to_i) end end + + update_desc = <<-EOT.unindent + Update the template contents. If a path is not provided the editor will + be launched to modify the current content. + EOT + + command :update, update_desc, :clusterid, [:file, nil] do + helper.perform_action(args[0],options,"modified") do |obj| + str = OpenNebulaHelper.update_template(args[0], obj, args[1]) + obj.update(str) + end + end end diff --git a/src/cluster/Cluster.cc b/src/cluster/Cluster.cc index 78b93ddd28..501c9fa5a2 100644 --- a/src/cluster/Cluster.cc +++ b/src/cluster/Cluster.cc @@ -33,6 +33,29 @@ const char * Cluster::db_bootstrap = "CREATE TABLE IF NOT EXISTS cluster_pool (" "gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, " "UNIQUE(name))"; +/* ************************************************************************ */ +/* Cluster :: Constructor/Destructor */ +/* ************************************************************************ */ + +Cluster::Cluster( + int id, + const string& name, + ClusterTemplate* cl_template): + PoolObjectSQL(id,CLUSTER,name,-1,-1,"","",table), + hosts("HOSTS"), + datastores("DATASTORES"), + vnets("VNETS") +{ + if (cl_template != 0) + { + obj_template = cl_template; + } + else + { + obj_template = new ClusterTemplate; + } +} + /* ------------------------------------------------------------------------ */ /* ------------------------------------------------------------------------ */ @@ -170,6 +193,7 @@ string& Cluster::to_xml(string& xml) const string host_collection_xml; string ds_collection_xml; string vnet_collection_xml; + string template_xml; oss << "" << @@ -179,7 +203,7 @@ string& Cluster::to_xml(string& xml) const hosts.to_xml(host_collection_xml) << datastores.to_xml(ds_collection_xml) << vnets.to_xml(vnet_collection_xml) << - + obj_template->to_xml(template_xml) << ""; xml = oss.str(); @@ -256,6 +280,18 @@ int Cluster::from_xml(const string& xml) ObjectXML::free_nodes(content); content.clear(); + // Get associated classes + ObjectXML::get_nodes("/CLUSTER/TEMPLATE", content); + + if (content.empty()) + { + return -1; + } + + rc += obj_template->from_xml_node(content[0]); + + ObjectXML::free_nodes(content); + if (rc != 0) { return -1; diff --git a/src/cluster/ClusterPool.cc b/src/cluster/ClusterPool.cc index 61d48d2aea..b3ff69e26c 100644 --- a/src/cluster/ClusterPool.cc +++ b/src/cluster/ClusterPool.cc @@ -72,7 +72,7 @@ int ClusterPool::allocate(string name, int * oid, string& error_str) } // Build a new Cluster object - cluster = new Cluster(-1, name); + cluster = new Cluster(-1, name, 0); // Insert the Object in the pool *oid = PoolSQL::allocate(cluster, error_str); diff --git a/src/oca/java/src/org/opennebula/client/cluster/Cluster.java b/src/oca/java/src/org/opennebula/client/cluster/Cluster.java index fdf1b75703..1edbe4a934 100644 --- a/src/oca/java/src/org/opennebula/client/cluster/Cluster.java +++ b/src/oca/java/src/org/opennebula/client/cluster/Cluster.java @@ -30,6 +30,7 @@ public class Cluster extends PoolElement{ private static final String ALLOCATE = METHOD_PREFIX + "allocate"; private static final String DELETE = METHOD_PREFIX + "delete"; private static final String INFO = METHOD_PREFIX + "info"; + private static final String UPDATE = METHOD_PREFIX + "update"; private static final String ADDHOST = METHOD_PREFIX + "addhost"; private static final String DELHOST = METHOD_PREFIX + "delhost"; private static final String ADDDATASTORE = METHOD_PREFIX + "adddatastore"; @@ -99,6 +100,19 @@ public class Cluster extends PoolElement{ return client.call(DELETE, id); } + /** + * Replaces the cluster contents. + * + * @param client XML-RPC Client. + * @param id The id of the target cluster we want to modify. + * @param new_template New template contents. + * @return If successful the message contains the cluster id. + */ + public static OneResponse update(Client client, int id, String new_template) + { + return client.call(UPDATE, id, new_template); + } + /** * Adds a Host to this Cluster * @@ -210,6 +224,17 @@ public class Cluster extends PoolElement{ return delete(client, id); } + /** + * Replaces the cluster template. + * + * @param new_template New cluster template. + * @return If successful the message contains the cluster id. + */ + public OneResponse update(String new_template) + { + return update(client, id, new_template); + } + /** * Adds a Host to this Cluster * diff --git a/src/oca/ruby/OpenNebula/Cluster.rb b/src/oca/ruby/OpenNebula/Cluster.rb index cdec2f5703..e6abb4c7a3 100644 --- a/src/oca/ruby/OpenNebula/Cluster.rb +++ b/src/oca/ruby/OpenNebula/Cluster.rb @@ -32,7 +32,8 @@ module OpenNebula :adddatastore => "cluster.adddatastore", :deldatastore => "cluster.deldatastore", :addvnet => "cluster.addvnet", - :delvnet => "cluster.delvnet" + :delvnet => "cluster.delvnet", + :update => "cluster.update", } # Creates a Cluster description with just its identifier @@ -156,6 +157,16 @@ module OpenNebula return rc end + # Replaces the template contents + # + # @param new_template [String] New template contents + # + # @return [nil, OpenNebula::Error] nil in case of success, Error + # otherwise + def update(new_template) + super(CLUSTER_METHODS[:update], new_template) + end + # --------------------------------------------------------------------- # Helpers to get information # --------------------------------------------------------------------- diff --git a/src/rm/RequestManager.cc b/src/rm/RequestManager.cc index a349134855..4c2135785b 100644 --- a/src/rm/RequestManager.cc +++ b/src/rm/RequestManager.cc @@ -268,6 +268,7 @@ void RequestManager::register_xml_methods() xmlrpc_c::methodPtr user_update(new UserUpdateTemplate()); xmlrpc_c::methodPtr datastore_update(new DatastoreUpdateTemplate()); xmlrpc_c::methodPtr doc_update(new DocumentUpdateTemplate()); + xmlrpc_c::methodPtr cluster_update(new ClusterUpdateTemplate()); // Allocate Methods xmlrpc_c::methodPtr vm_allocate(new VirtualMachineAllocate()); @@ -468,6 +469,7 @@ void RequestManager::register_xml_methods() RequestManagerRegistry.addMethod("one.cluster.allocate",cluster_allocate); RequestManagerRegistry.addMethod("one.cluster.delete", cluster_delete); RequestManagerRegistry.addMethod("one.cluster.info", cluster_info); + RequestManagerRegistry.addMethod("one.cluster.update", cluster_update); RequestManagerRegistry.addMethod("one.cluster.addhost", cluster_addhost); RequestManagerRegistry.addMethod("one.cluster.delhost", cluster_delhost); From 792dcf01b31132eff520f7babcb61eec41aeb941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 29 Jun 2012 12:44:04 +0200 Subject: [PATCH 18/24] Bug #1306: Clusters can use the datastore set in SYSTEM_DS, Datastores can have SYSTEM = YES in the template --- include/Cluster.h | 17 ++++++++ include/Datastore.h | 5 +++ src/datastore/Datastore.cc | 55 ++++++++++++++++++++++---- src/datastore/DatastorePool.cc | 2 +- src/rm/RequestManagerVirtualMachine.cc | 3 +- 5 files changed, 72 insertions(+), 10 deletions(-) diff --git a/include/Cluster.h b/include/Cluster.h index 002328bd05..9c4641b7c2 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -31,6 +31,23 @@ class Cluster : public PoolObjectSQL { public: + /** + * Returns the SYSTEM_DS attribute, or the system DS id if it is not defined + * + * @return the SYSTEM_DS attribute, or the system DS id if it is not defined + */ + int get_ds_id() + { + int ds_id; + + if ( obj_template->get("SYSTEM_DS", ds_id) == false ) + { + ds_id = DatastorePool::SYSTEM_DS_ID; + } + + return ds_id; + } + // ************************************************************************* // Object Collections (Public) // ************************************************************************* diff --git a/include/Datastore.h b/include/Datastore.h index ceaf552fde..1941b02342 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -134,6 +134,11 @@ private: */ string base_path; + /** + * 1 if this is a system DS + */ + int system_ds; + /** * Disk types for the Images created in this datastore */ diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 8b40ddc925..96908e63cb 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -19,6 +19,8 @@ #include "NebulaLog.h" #include "Nebula.h" +#define TO_UPPER(S) transform(S.begin(),S.end(),S.begin(),(int(*)(int))toupper) + const char * Datastore::table = "datastore_pool"; const char * Datastore::db_names = @@ -97,6 +99,7 @@ int Datastore::insert(SqlDB *db, string& error_str) int rc; ostringstream oss; string s_disk_type; + string s_system_ds; Nebula& nd = Nebula::instance(); @@ -108,8 +111,22 @@ int Datastore::insert(SqlDB *db, string& error_str) // NAME is checked in DatastorePool::allocate get_template_attribute("DS_MAD", ds_mad); + get_template_attribute("SYSTEM", s_system_ds); - if ( ds_mad.empty() == true ) + TO_UPPER(s_system_ds); + + system_ds = (s_system_ds == "YES"); + + if ( system_ds == 1 ) + { + if ( !ds_mad.empty() ) + { + goto error_exclusive; + } + + ds_mad = "-"; + } + else if ( ds_mad.empty() == true ) { goto error_ds; } @@ -152,6 +169,10 @@ int Datastore::insert(SqlDB *db, string& error_str) return rc; +error_exclusive: + error_str = "SYSTEM datastores cannot have DS_MAD defined."; + goto error_common; + error_ds: error_str = "No DS_MAD in template."; goto error_common; @@ -273,6 +294,7 @@ string& Datastore::to_xml(string& xml) const "" << ds_mad << "" << "" << tm_mad << "" << "" << base_path << "" << + "" << system_ds << "" << "" << disk_type << "" << "" << cluster_id << "" << "" << cluster << "" << @@ -307,6 +329,7 @@ int Datastore::from_xml(const string& xml) rc += xpath(ds_mad, "/DATASTORE/DS_MAD", "not_found"); rc += xpath(tm_mad, "/DATASTORE/TM_MAD", "not_found"); rc += xpath(base_path, "/DATASTORE/BASE_PATH", "not_found"); + rc += xpath(system_ds, "/DATASTORE/SYSTEM", -1); rc += xpath(int_disk_type,"/DATASTORE/DISK_TYPE", -1); rc += xpath(cluster_id, "/DATASTORE/CLUSTER_ID", -1); @@ -354,14 +377,15 @@ int Datastore::from_xml(const string& xml) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int Datastore::replace_template(const string& tmpl_str, string& error) +int Datastore::replace_template(const string& tmpl_str, string& error_str) { string new_ds_mad; string new_tm_mad; + string s_system_ds; int rc; - rc = PoolObjectSQL::replace_template(tmpl_str, error); + rc = PoolObjectSQL::replace_template(tmpl_str, error_str); if ( rc != 0 ) { @@ -369,15 +393,32 @@ int Datastore::replace_template(const string& tmpl_str, string& error) } get_template_attribute("DS_MAD", new_ds_mad); + get_template_attribute("SYSTEM", s_system_ds); + + TO_UPPER(s_system_ds); + + if ( !s_system_ds.empty() ) + { + system_ds = (s_system_ds == "YES"); + } + + if ( system_ds == 1 ) + { + replace_template_attribute("SYSTEM", "YES"); + + new_ds_mad = "-"; + } + else + { + obj_template->erase("SYSTEM"); + } if ( !new_ds_mad.empty() ) { ds_mad = new_ds_mad; } - else - { - replace_template_attribute("DS_MAD", ds_mad); - } + + replace_template_attribute("DS_MAD", ds_mad); get_template_attribute("TM_MAD", new_tm_mad); diff --git a/src/datastore/DatastorePool.cc b/src/datastore/DatastorePool.cc index b38318fc04..c8639eca69 100644 --- a/src/datastore/DatastorePool.cc +++ b/src/datastore/DatastorePool.cc @@ -53,7 +53,7 @@ DatastorePool::DatastorePool(SqlDB * db): // --------------------------------------------------------------------- oss << "NAME = " << SYSTEM_DS_NAME << endl - << "DS_MAD = -" << endl + << "SYSTEM = YES" << endl << "TM_MAD = shared"; ds_tmpl = new DatastoreTemplate; diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 90ec095ced..cad51340ce 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -145,8 +145,7 @@ int RequestManagerVirtualMachine::get_host_information(int hid, return -1; } - // TODO: ds_id = cluster->get_datastore() - ds_id = DatastorePool::SYSTEM_DS_ID; + ds_id = cluster->get_ds_id(); cluster->unlock(); From fd28ff9d9f5da8f58dd71adc36d94a06e41764f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 29 Jun 2012 15:09:25 +0200 Subject: [PATCH 19/24] Bug #1306: If the cluster has a SYSTEM_DS set, check that it is actually a system type ds. Do not allow image registration in any system type DS. --- include/Cluster.h | 1 + include/Datastore.h | 10 ++++++++++ src/datastore/Datastore.cc | 12 +++++++++--- src/rm/RequestManagerAllocate.cc | 25 ++++++++++++++----------- src/rm/RequestManagerVirtualMachine.cc | 18 ++++++++++++++++++ 5 files changed, 52 insertions(+), 14 deletions(-) diff --git a/include/Cluster.h b/include/Cluster.h index 9c4641b7c2..a6e8415e06 100644 --- a/include/Cluster.h +++ b/include/Cluster.h @@ -96,6 +96,7 @@ public: */ int add_datastore(int id, string& error_msg) { + // TODO: should fail for any system DS? if ( id == DatastorePool::SYSTEM_DS_ID ) { ostringstream oss; diff --git a/include/Datastore.h b/include/Datastore.h index 1941b02342..2b03953032 100644 --- a/include/Datastore.h +++ b/include/Datastore.h @@ -91,6 +91,16 @@ public: { return disk_type; }; + + /** + * Returns true if this is a system datastore + * @return true if this is a system datastore + */ + bool is_system() const + { + return system_ds == 1; + }; + /** * Modifies the given VM disk attribute adding the relevant datastore * attributes diff --git a/src/datastore/Datastore.cc b/src/datastore/Datastore.cc index 96908e63cb..bfed67afaa 100644 --- a/src/datastore/Datastore.cc +++ b/src/datastore/Datastore.cc @@ -49,7 +49,8 @@ Datastore::Datastore( Clusterable(cluster_id, cluster_name), ds_mad(""), tm_mad(""), - base_path("") + base_path(""), + system_ds(0) { group_u = 1; @@ -395,10 +396,15 @@ int Datastore::replace_template(const string& tmpl_str, string& error_str) get_template_attribute("DS_MAD", new_ds_mad); get_template_attribute("SYSTEM", s_system_ds); - TO_UPPER(s_system_ds); - if ( !s_system_ds.empty() ) + if ( oid == DatastorePool::SYSTEM_DS_ID ) { + system_ds = 1; + } + else if ( !s_system_ds.empty() ) + { + TO_UPPER(s_system_ds); + system_ds = (s_system_ds == "YES"); } diff --git a/src/rm/RequestManagerAllocate.cc b/src/rm/RequestManagerAllocate.cc index 3f05704c5f..2da96e857b 100644 --- a/src/rm/RequestManagerAllocate.cc +++ b/src/rm/RequestManagerAllocate.cc @@ -322,17 +322,6 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, // ------------------------- Check Datastore exists ------------------------ - if ( ds_id == DatastorePool::SYSTEM_DS_ID ) - { - ostringstream oss; - - oss << "New images cannot be allocated in the system datastore."; - failure_response(INTERNAL, allocate_error(oss.str()), att); - - delete tmpl; - return; - } - if ((ds = dspool->get(ds_id,true)) == 0 ) { failure_response(NO_EXISTS, @@ -343,6 +332,20 @@ void ImageAllocate::request_execute(xmlrpc_c::paramList const& params, return; } + if ( ds->is_system() ) + { + ostringstream oss; + + ds->unlock(); + + oss << "New images cannot be allocated in a system datastore."; + failure_response(INTERNAL, allocate_error(oss.str()), att); + + delete tmpl; + + return; + } + ds->get_permissions(ds_perms); ds_name = ds->get_name(); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index cad51340ce..f62e42e567 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -160,6 +160,24 @@ int RequestManagerVirtualMachine::get_host_information(int hid, return -1; } + if ( ds->is_system() == false ) + { + ostringstream oss; + + ds->unlock(); + + oss << object_name(PoolObjectSQL::CLUSTER) + << " [" << cluster_id << "] has its SYSTEM_DS set to " + << object_name(PoolObjectSQL::DATASTORE) + << " [" << ds_id << "], but it is not a system one."; + + failure_response(INTERNAL, + request_error(oss.str(),""), + att); + + return -1; + } + tm = ds->get_tm_mad(); ds->unlock(); From 1327f28fab29096fae745332fb27e36399f410d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 29 Jun 2012 16:48:43 +0200 Subject: [PATCH 20/24] Bug #1306: Use the System DS id to generate the VM system dir --- include/History.h | 3 +++ include/RequestManagerVirtualMachine.h | 4 +++- include/VirtualMachine.h | 3 ++- src/rm/RequestManagerVirtualMachine.cc | 17 +++++++++++------ src/vm/History.cc | 9 +++++++-- src/vm/VirtualMachine.cc | 10 +++++++--- 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/include/History.h b/include/History.h index 7852cfed46..f9a9dd9b71 100644 --- a/include/History.h +++ b/include/History.h @@ -47,6 +47,7 @@ public: const string& vmm, const string& vnm, const string& tmm, + int ds_id, const string& vm_info); ~History(){}; @@ -92,6 +93,8 @@ private: string vnm_mad_name; string tm_mad_name; + int ds_id; + time_t stime; time_t etime; diff --git a/include/RequestManagerVirtualMachine.h b/include/RequestManagerVirtualMachine.h index f4c8866cac..284469508e 100644 --- a/include/RequestManagerVirtualMachine.h +++ b/include/RequestManagerVirtualMachine.h @@ -57,7 +57,8 @@ protected: AuthRequest::Operation op); int get_host_information(int hid, string& name, string& vmm, string& vnm, - string& tm, RequestAttributes& att, PoolObjectAuth& host_perms); + string& tm, int& ds_id, RequestAttributes& att, + PoolObjectAuth& host_perms); int add_history(VirtualMachine * vm, int hid, @@ -65,6 +66,7 @@ protected: const string& vmm_mad, const string& vnm_mad, const string& tm_mad, + int ds_id, RequestAttributes& att); VirtualMachine * get_vm(int id, RequestAttributes& att); diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 36eeacea67..58014dbf3a 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -243,7 +243,8 @@ public: const string& hostname, const string& vmm_mad, const string& vnm_mad, - const string& tm_mad); + const string& tm_mad, + int ds_id); /** * Duplicates the last history record. Only the host related fields are diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index f62e42e567..2db8e65c12 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -100,6 +100,7 @@ int RequestManagerVirtualMachine::get_host_information(int hid, string& vmm, string& vnm, string& tm, + int& ds_id, RequestAttributes& att, PoolObjectAuth& host_perms) { @@ -111,7 +112,6 @@ int RequestManagerVirtualMachine::get_host_information(int hid, Datastore * ds; int cluster_id; - int ds_id; host = hpool->get(hid,true); @@ -213,6 +213,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, const string& vmm_mad, const string& vnm_mad, const string& tm_mad, + int ds_id, RequestAttributes& att) { string vmdir; @@ -220,7 +221,7 @@ int RequestManagerVirtualMachine::add_history(VirtualMachine * vm, VirtualMachinePool * vmpool = static_cast(pool); - vm->add_history(hid,hostname,vmm_mad,vnm_mad,tm_mad); + vm->add_history(hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id); rc = vmpool->update_history(vm); @@ -366,13 +367,15 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, string vmm_mad; string vnm_mad; string tm_mad; + int ds_id; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad,att, host_perms) != 0) + if (get_host_information( + hid,hostname,vmm_mad,vnm_mad,tm_mad, ds_id, att, host_perms) != 0) { return; } @@ -399,7 +402,7 @@ void VirtualMachineDeploy::request_execute(xmlrpc_c::paramList const& paramList, return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id,att) != 0) { vm->unlock(); return; @@ -428,6 +431,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList string vmm_mad; string vnm_mad; string tm_mad; + int ds_id; int id = xmlrpc_c::value_int(paramList.getInt(1)); int hid = xmlrpc_c::value_int(paramList.getInt(2)); @@ -435,7 +439,8 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList bool auth = false; - if (get_host_information(hid,hostname,vmm_mad,vnm_mad,tm_mad,att, host_perms) != 0) + if (get_host_information( + hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id, att, host_perms) != 0) { return; } @@ -464,7 +469,7 @@ void VirtualMachineMigrate::request_execute(xmlrpc_c::paramList const& paramList return; } - if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,att) != 0) + if ( add_history(vm,hid,hostname,vmm_mad,vnm_mad,tm_mad,ds_id,att) != 0) { vm->unlock(); return; diff --git a/src/vm/History.cc b/src/vm/History.cc index 415c990060..c7aaf607ca 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -45,6 +45,7 @@ History::History( vmm_mad_name(""), vnm_mad_name(""), tm_mad_name(""), + ds_id(0), stime(0), etime(0), prolog_stime(0), @@ -66,6 +67,7 @@ History::History( const string& _vmm, const string& _vnm, const string& _tmm, + int _ds_id, const string& _vm_info): oid(_oid), seq(_seq), @@ -74,6 +76,7 @@ History::History( vmm_mad_name(_vmm), vnm_mad_name(_vnm), tm_mad_name(_tmm), + ds_id(_ds_id), stime(0), etime(0), prolog_stime(0), @@ -126,7 +129,7 @@ void History::non_persistent_data() os.str(""); nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); - os << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid; + os << ds_location << "/" << ds_id << "/" << oid; vm_rhome = os.str(); @@ -296,6 +299,7 @@ string& History::to_xml(string& xml, bool database) const "" << vmm_mad_name << ""<< "" << vnm_mad_name << ""<< "" << tm_mad_name << "" << + "" << ds_id << "" << "" << prolog_stime << ""<< "" << prolog_etime << ""<< "" << running_stime << ""<< @@ -334,7 +338,8 @@ int History::rebuild_attributes() xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); // TODO: add TMMAD element in onedb migrator - rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); + rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); + rc += xpath(ds_id , "/HISTORY/DS_ID", 0); rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 46ec12eb05..2080ca731b 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -827,7 +827,8 @@ void VirtualMachine::add_history( const string& hostname, const string& vmm_mad, const string& vnm_mad, - const string& tm_mad) + const string& tm_mad, + int ds_id) { ostringstream os; int seq; @@ -853,6 +854,7 @@ void VirtualMachine::add_history( vmm_mad, vnm_mad, tm_mad, + ds_id, vm_xml); history_records.push_back(history); @@ -880,6 +882,7 @@ void VirtualMachine::cp_history() history->vmm_mad_name, history->vnm_mad_name, history->tm_mad_name, + history->ds_id, vm_xml); previous_history = history; @@ -910,6 +913,7 @@ void VirtualMachine::cp_previous_history() previous_history->vmm_mad_name, previous_history->vnm_mad_name, previous_history->tm_mad_name, + previous_history->ds_id, vm_xml); previous_history = history; @@ -1984,7 +1988,7 @@ string VirtualMachine::get_remote_system_dir() const Nebula& nd = Nebula::instance(); nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); - oss << ds_location << "/" << DatastorePool::SYSTEM_DS_ID << "/" << oid; + oss << ds_location << "/" << history->ds_id << "/" << oid; return oss.str(); } @@ -1997,7 +2001,7 @@ string VirtualMachine::get_system_dir() const ostringstream oss; Nebula& nd = Nebula::instance(); - oss << nd.get_ds_location() << DatastorePool::SYSTEM_DS_ID << "/"<< oid; + oss << nd.get_ds_location() << history->ds_id << "/"<< oid; return oss.str(); }; From df0e1ce13a05130c93eec49ca357861f1782282b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Fri, 29 Jun 2012 18:42:03 +0200 Subject: [PATCH 21/24] Bug #1306: Add onedb migrator to 3.6.0 --- install.sh | 1 + src/onedb/3.5.80_to_3.6.0.rb | 146 +++++++++++++++++++++++++++++++++++ src/vm/History.cc | 3 - 3 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 src/onedb/3.5.80_to_3.6.0.rb diff --git a/install.sh b/install.sh index 02743f1165..c0bc6a0712 100755 --- a/install.sh +++ b/install.sh @@ -925,6 +925,7 @@ ONEDB_MIGRATOR_FILES="src/onedb/2.0_to_2.9.80.rb \ src/onedb/3.3.80_to_3.4.0.rb \ src/onedb/3.4.0_to_3.4.1.rb \ src/onedb/3.4.1_to_3.5.80.rb \ + src/onedb/3.5.80_to_3.6.0.rb \ src/onedb/onedb.rb \ src/onedb/onedb_backend.rb" diff --git a/src/onedb/3.5.80_to_3.6.0.rb b/src/onedb/3.5.80_to_3.6.0.rb new file mode 100644 index 0000000000..cf8b892eb9 --- /dev/null +++ b/src/onedb/3.5.80_to_3.6.0.rb @@ -0,0 +1,146 @@ +# -------------------------------------------------------------------------- # +# 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. # +#--------------------------------------------------------------------------- # + +require "rexml/document" +include REXML + +module Migrator + def db_version + "3.6.0" + end + + def one_version + "OpenNebula 3.6.0" + end + + def up + + @db.run "ALTER TABLE cluster_pool RENAME TO old_cluster_pool;" + @db.run "CREATE TABLE cluster_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + @db.fetch("SELECT * FROM old_cluster_pool") do |row| + doc = Document.new(row[:body]) + + doc.root.add_element("TEMPLATE") + + @db[:cluster_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_cluster_pool;" + + + @db.run "ALTER TABLE datastore_pool RENAME TO old_datastore_pool;" + @db.run "CREATE TABLE datastore_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER, UNIQUE(name));" + + system_tm = "" + + @db.fetch("SELECT * FROM old_datastore_pool WHERE oid = 0") do |row| + doc = Document.new(row[:body]) + + doc.root.each_element("TM_MAD") { |e| + system_tm = e.text + } + + doc.root.add_element("SYSTEM").text = "1" + + @db[:datastore_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.fetch("SELECT * FROM old_datastore_pool WHERE oid > 0") do |row| + doc = Document.new(row[:body]) + + doc.root.add_element("SYSTEM").text = "0" + + @db[:datastore_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_datastore_pool;" + + + @db.run "ALTER TABLE vm_pool RENAME TO old_vm_pool;" + @db.run "CREATE TABLE vm_pool (oid INTEGER PRIMARY KEY, name VARCHAR(128), body TEXT, uid INTEGER, gid INTEGER, last_poll INTEGER, state INTEGER, lcm_state INTEGER, owner_u INTEGER, group_u INTEGER, other_u INTEGER);" + + @db.fetch("SELECT * FROM old_vm_pool") do |row| + doc = Document.new(row[:body]) + + doc.root.each_element("HISTORY_RECORDS/HISTORY") { |e| + e.add_element("TMMAD").text = system_tm + e.add_element("DS_ID").text = "0" + } + + @db[:vm_pool].insert( + :oid => row[:oid], + :name => row[:name], + :body => doc.root.to_s, + :uid => row[:uid], + :gid => row[:gid], + :last_poll => row[:last_poll], + :state => row[:state], + :lcm_state => row[:lcm_state], + :owner_u => row[:owner_u], + :group_u => row[:group_u], + :other_u => row[:other_u]) + end + + @db.run "DROP TABLE old_vm_pool;" + + + @db.run "ALTER TABLE history RENAME TO old_history;" + @db.run "CREATE TABLE history (vid INTEGER, seq INTEGER, body TEXT, stime INTEGER, etime INTEGER, PRIMARY KEY(vid,seq));" + + @db.fetch("SELECT * FROM old_history") do |row| + doc = Document.new(row[:body]) + + doc.root.add_element("TMMAD").text = system_tm + doc.root.add_element("DS_ID").text = "0" + + @db[:history].insert( + :vid => row[:vid], + :seq => row[:seq], + :body => doc.root.to_s, + :stime => row[:stime], + :etime => row[:etime]) + end + + @db.run "DROP TABLE old_history;" + + return true + end +end diff --git a/src/vm/History.cc b/src/vm/History.cc index c7aaf607ca..cbbe4ba072 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -336,11 +336,8 @@ int History::rebuild_attributes() rc += xpath(etime , "/HISTORY/ETIME", 0); rc += xpath(vmm_mad_name , "/HISTORY/VMMMAD", "not_found"); xpath(vnm_mad_name , "/HISTORY/VNMMAD", "dummy"); - - // TODO: add TMMAD element in onedb migrator rc += xpath(tm_mad_name , "/HISTORY/TMMAD", "not_found"); rc += xpath(ds_id , "/HISTORY/DS_ID", 0); - rc += xpath(prolog_stime , "/HISTORY/PSTIME", 0); rc += xpath(prolog_etime , "/HISTORY/PETIME", 0); rc += xpath(running_stime , "/HISTORY/RSTIME", 0); From 54dccb3a46729be168354c280dc57e4e694bd12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 2 Jul 2012 12:46:17 +0200 Subject: [PATCH 22/24] Bug #1306: Fix bug, deployment didn't work for Hosts in cluster -1 (none) --- src/rm/RequestManagerVirtualMachine.cc | 29 ++++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 2db8e65c12..eea341cfc6 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -134,20 +134,27 @@ int RequestManagerVirtualMachine::get_host_information(int hid, host->unlock(); - cluster = nd.get_clpool()->get(cluster_id, true); - - if ( cluster == 0 ) + if ( cluster_id != -1 ) { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), - att); + cluster = nd.get_clpool()->get(cluster_id, true); - return -1; + if ( cluster == 0 ) + { + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); + + return -1; + } + + ds_id = cluster->get_ds_id(); + + cluster->unlock(); + } + else + { + ds_id = DatastorePool::SYSTEM_DS_ID; } - - ds_id = cluster->get_ds_id(); - - cluster->unlock(); ds = nd.get_dspool()->get(ds_id, true); From 1ee82ca6263922f085ce4a02f72fd36a10542d90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= Date: Mon, 2 Jul 2012 14:50:21 +0200 Subject: [PATCH 23/24] Bug #1306: Update xsd files --- share/doc/xsd/acct.xsd | 2 ++ share/doc/xsd/cluster.xsd | 1 + share/doc/xsd/datastore.xsd | 1 + share/doc/xsd/test.sh | 4 ++-- share/doc/xsd/vm.xsd | 2 ++ 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/share/doc/xsd/acct.xsd b/share/doc/xsd/acct.xsd index 3a96b5d37a..e8ff06e4c9 100644 --- a/share/doc/xsd/acct.xsd +++ b/share/doc/xsd/acct.xsd @@ -21,6 +21,8 @@ + + diff --git a/share/doc/xsd/cluster.xsd b/share/doc/xsd/cluster.xsd index 17df53e31f..7fdacacb8d 100644 --- a/share/doc/xsd/cluster.xsd +++ b/share/doc/xsd/cluster.xsd @@ -27,6 +27,7 @@ + diff --git a/share/doc/xsd/datastore.xsd b/share/doc/xsd/datastore.xsd index c1f5dfac98..e3a0788e83 100644 --- a/share/doc/xsd/datastore.xsd +++ b/share/doc/xsd/datastore.xsd @@ -28,6 +28,7 @@ + diff --git a/share/doc/xsd/test.sh b/share/doc/xsd/test.sh index ede292192a..50d77e06a5 100755 --- a/share/doc/xsd/test.sh +++ b/share/doc/xsd/test.sh @@ -33,8 +33,8 @@ onegroup create newgroup # Host -onehost create host01 --im im_test --vm vmm_test --net dummy -onehost create host02 --im im_test --vm vmm_test --net dummy +onehost create host01 --im im_dummy --vm vmm_dummy --net dummy +onehost create host02 --im im_dummy --vm vmm_dummy --net dummy onecluster addhost newcluster host02 diff --git a/share/doc/xsd/vm.xsd b/share/doc/xsd/vm.xsd index 134f196d2d..81155bd02b 100644 --- a/share/doc/xsd/vm.xsd +++ b/share/doc/xsd/vm.xsd @@ -95,6 +95,8 @@ + + From 11f5c8c2da1661d79f8cf87da0caff0e870c9f7e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Mon, 2 Jul 2012 18:06:07 +0200 Subject: [PATCH 24/24] bug #1315: call MV/DELETE actions for volatile disks --- include/VirtualMachine.h | 29 +++++ src/tm/TransferManager.cc | 223 ++++++++++++++++++++++++++------------ 2 files changed, 183 insertions(+), 69 deletions(-) diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 58014dbf3a..8902f58913 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -320,6 +320,35 @@ public: return previous_history->vnm_mad_name; }; + + /** + * Returns the datastore ID of the system DS for the host. The hasHistory() + * function MUST be called before this one. + * @return the ds id + */ + string get_ds_id() const + { + ostringstream oss; + + oss << history->ds_id; + + return oss.str(); + }; + + /** + * Returns the datastore ID of the system DS for the previous host. + * The hasPreviousHistory() function MUST be called before this one. + * @return the TM mad name + */ + string get_previous_ds_id() const + { + ostringstream oss; + + oss << previous_history->ds_id; + + return oss.str(); + }; + /** * Returns the TM driver name for the current host. The hasHistory() * function MUST be called before this one. diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 680a5f894f..d31f81cd2e 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -499,6 +499,19 @@ error_common: /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +static bool isVolatile(const VectorAttribute * disk) +{ + string type; + + type = disk->vector_value("TYPE"); + transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper); + + return ( type == "SWAP" || type == "FS"); +} + +/* -------------------------------------------------------------------------- */ +/* -------------------------------------------------------------------------- */ + void TransferManager::prolog_migr_action(int vid) { ofstream xfr; @@ -508,6 +521,7 @@ void TransferManager::prolog_migr_action(int vid) const VectorAttribute * disk; string tm_mad; string vm_tm_mad; + string vm_ds_id; string ds_id; int disk_id; @@ -534,10 +548,11 @@ void TransferManager::prolog_migr_action(int vid) goto error_history; } - vm_tm_mad = vm->get_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); - if ( tm_md == 0 || vm_tm_mad.empty() ) + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) { goto error_drivers; } @@ -565,13 +580,22 @@ void TransferManager::prolog_migr_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if ( tm_mad.empty() || ds_id.empty() ) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //MV tm_mad prev_host:remote_system_dir/disk.i host:remote_system_dir/disk.i vmid dsid @@ -593,7 +617,7 @@ void TransferManager::prolog_migr_action(int vid) << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -637,6 +661,7 @@ void TransferManager::prolog_resume_action(int vid) const VectorAttribute * disk; string tm_mad; string vm_tm_mad; + string vm_ds_id; string ds_id; int disk_id; @@ -663,10 +688,11 @@ void TransferManager::prolog_resume_action(int vid) goto error_history; } - vm_tm_mad = vm->get_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); - if ( tm_md == 0 || vm_tm_mad.empty() ) + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) { goto error_drivers; } @@ -693,13 +719,22 @@ void TransferManager::prolog_resume_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if ( tm_mad.empty() || ds_id.empty() ) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //MV tm_mad fe:system_dir/disk.i host:remote_system_dir/disk.i vmid dsid @@ -719,7 +754,7 @@ void TransferManager::prolog_resume_action(int vid) << nd.get_nebula_hostname() << ":"<< vm->get_system_dir() << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir()<< " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -764,13 +799,22 @@ void TransferManager::epilog_transfer_command( string ds_id; int disk_index; - save = disk->vector_value("SAVE"); - ds_id = disk->vector_value("DATASTORE_ID"); - tm_mad = disk->vector_value("TM_MAD"); - - if ( save.empty() || ds_id.empty() || tm_mad.empty() ) + if ( isVolatile(disk) == true ) { - return; + save = "NO"; + tm_mad = vm->get_tm_mad(); + ds_id = vm->get_ds_id(); + } + else + { + save = disk->vector_value("SAVE"); + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( save.empty() || ds_id.empty() || tm_mad.empty() ) + { + return; + } } disk->vector_value("DISK_ID", disk_index); @@ -826,9 +870,10 @@ void TransferManager::epilog_action(int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string vm_tm_mad; - string error_str; + string xfr_name; + string vm_tm_mad; + string vm_ds_id; + string error_str; const VectorAttribute * disk; @@ -855,10 +900,11 @@ void TransferManager::epilog_action(int vid) goto error_history; } - vm_tm_mad = vm->get_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); - if ( tm_md == 0 || vm_tm_mad.empty() ) + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) { goto error_drivers; } @@ -893,7 +939,7 @@ void TransferManager::epilog_action(int vid) << vm_tm_mad << " " << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -932,11 +978,14 @@ void TransferManager::epilog_stop_action(int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string tm_mad; - string vm_tm_mad; - string ds_id; - int disk_id; + + string xfr_name; + string tm_mad; + string vm_tm_mad; + string vm_ds_id; + string ds_id; + + int disk_id; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -962,10 +1011,11 @@ void TransferManager::epilog_stop_action(int vid) goto error_history; } - vm_tm_mad = vm->get_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); - if ( tm_md == 0 || vm_tm_mad.empty() ) + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) { goto error_drivers; } @@ -992,13 +1042,22 @@ void TransferManager::epilog_stop_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if (tm_mad.empty() || ds_id.empty()) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //MV tm_mad host:remote_system_dir/disk.i fe:system_dir/disk.i vmid dsid @@ -1018,7 +1077,7 @@ void TransferManager::epilog_stop_action(int vid) << vm->get_hostname() << ":" << vm->get_remote_system_dir() << " " << nd.get_nebula_hostname() << ":" << vm->get_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close(); @@ -1058,11 +1117,14 @@ void TransferManager::epilog_delete_action(bool local, int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string vm_tm_mad; - string tm_mad; - string ds_id; - int disk_id; + + string xfr_name; + string vm_tm_mad; + string tm_mad; + string vm_ds_id; + string ds_id; + + int disk_id; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -1088,10 +1150,11 @@ void TransferManager::epilog_delete_action(bool local, int vid) goto error_history; } - vm_tm_mad = vm->get_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_tm_mad(); + vm_ds_id = vm->get_ds_id(); + tm_md = get(); - if ( tm_md == 0 || vm_tm_mad.empty() ) + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty()) { goto error_drivers; } @@ -1118,13 +1181,22 @@ void TransferManager::epilog_delete_action(bool local, int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if ( tm_mad.empty() || ds_id.empty() ) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } if ( local ) @@ -1156,7 +1228,7 @@ void TransferManager::epilog_delete_action(bool local, int vid) << vm_tm_mad << " " << nd.get_nebula_hostname() <<":"<< vm->get_system_dir() << " " << vm->get_oid() << " " - << "0"; + << vm_ds_id; } else { @@ -1165,7 +1237,7 @@ void TransferManager::epilog_delete_action(bool local, int vid) << vm_tm_mad << " " << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0"; + << vm_ds_id; } xfr.close(); @@ -1207,11 +1279,14 @@ void TransferManager::epilog_delete_previous_action(int vid) { ofstream xfr; ostringstream os; - string xfr_name; - string vm_tm_mad; - string tm_mad; - string ds_id; - int disk_id; + + string xfr_name; + string vm_tm_mad; + string tm_mad; + string vm_ds_id; + string ds_id; + + int disk_id; VirtualMachine * vm; Nebula& nd = Nebula::instance(); @@ -1237,10 +1312,11 @@ void TransferManager::epilog_delete_previous_action(int vid) goto error_history; } - vm_tm_mad = vm->get_previous_tm_mad(); - tm_md = get(); + vm_tm_mad = vm->get_previous_tm_mad(); + vm_ds_id = vm->get_previous_ds_id(); + tm_md = get(); - if ( tm_md == 0 || vm_tm_mad.empty() ) + if ( tm_md == 0 || vm_tm_mad.empty() || vm_ds_id.empty() ) { goto error_drivers; } @@ -1267,13 +1343,22 @@ void TransferManager::epilog_delete_previous_action(int vid) continue; } - tm_mad = disk->vector_value("TM_MAD"); - ds_id = disk->vector_value("DATASTORE_ID"); disk->vector_value_str("DISK_ID", disk_id); - if (tm_mad.empty() || ds_id.empty()) + if ( isVolatile(disk) == true ) { - continue; + tm_mad = vm_tm_mad; + ds_id = vm_ds_id; + } + else + { + tm_mad = disk->vector_value("TM_MAD"); + ds_id = disk->vector_value("DATASTORE_ID"); + + if ( tm_mad.empty() || ds_id.empty() ) + { + continue; + } } //DELETE tm_mad prev_host:remote_system_dir/disk.i vmid ds_id @@ -1290,7 +1375,7 @@ void TransferManager::epilog_delete_previous_action(int vid) << vm_tm_mad << " " << vm->get_previous_hostname() <<":"<< vm->get_remote_system_dir() << " " << vm->get_oid() << " " - << "0" << endl; + << vm_ds_id << endl; xfr.close();