From fed93cdaf82e6515e8d2242e01c645c5f56e5a8d Mon Sep 17 00:00:00 2001 From: juanmont Date: Wed, 26 Jul 2017 14:59:35 +0200 Subject: [PATCH 01/40] F #4977 Removed MarketPlaceApp from OpenNebula --- include/MarketPlaceAppPool.h | 39 ++++++++++++++++++++++++++ src/market/MarketPlaceAppPool.cc | 10 ++++++- src/market/MarketPlaceManagerDriver.cc | 31 ++++++++++++++++++++ 3 files changed, 79 insertions(+), 1 deletion(-) diff --git a/include/MarketPlaceAppPool.h b/include/MarketPlaceAppPool.h index bb39389057..01c80af4d9 100644 --- a/include/MarketPlaceAppPool.h +++ b/include/MarketPlaceAppPool.h @@ -145,6 +145,45 @@ public: { return new MarketPlaceApp(-1,-1,"","", 0, 0); }; + + /** + * Erease map element + */ + void drop_map_check(const std::string& name){ + if (map_check.find( name ) != map_check.end()){ + map::iterator it; + it=map_check.find(name); + map_check.erase (it); + } + } + + /** + * Check an element into map + */ + bool test_map_check(const std::string& name){ + map_check[name]++; + if (map_check[name] > 0){ + return true; + } + return false; + } +private: + map map_check; + + + void insert_map_check(const std::string& name){ + map_check.insert(make_pair(name, -1)); + } + void reset_map_check(const std::string& name){ + if (name != "") { + if (map_check.find( name ) != map_check.end()){ + map_check[name] = -1; + } + else{ + insert_map_check(name); + } + } + } }; #endif /*MARKETPLACE_POOL_H_*/ diff --git a/src/market/MarketPlaceAppPool.cc b/src/market/MarketPlaceAppPool.cc index 9a40db1183..68c2d64e7e 100644 --- a/src/market/MarketPlaceAppPool.cc +++ b/src/market/MarketPlaceAppPool.cc @@ -128,6 +128,11 @@ int MarketPlaceAppPool:: allocate( *oid = PoolSQL::allocate(mp, error_str); + // ------------------------------------------------------------------------ + // Insert id into map_check + // -------------------------------------------------------------------------- + insert_map_check(name); + return *oid; error_duplicated: @@ -183,6 +188,8 @@ int MarketPlaceAppPool::drop(PoolObjectSQL * objsql, std::string& error_msg) return 0; } + drop_map_check(objsql->get_name()); + return PoolSQL::drop(objsql, error_msg); } @@ -229,6 +236,7 @@ int MarketPlaceAppPool::import(const std::string& t64, int mp_id, if( mp_aux != 0 ) //Marketplace app already imported { + reset_map_check(app->name); if ( mp_aux->version != app->version || mp_aux->md5 != app->md5 ) { mp_aux->from_template64(t64, error_str); @@ -255,7 +263,7 @@ int MarketPlaceAppPool::import(const std::string& t64, int mp_id, return oid; } - + insert_map_check(app->name); return PoolSQL::allocate(app, error_str); } diff --git a/src/market/MarketPlaceManagerDriver.cc b/src/market/MarketPlaceManagerDriver.cc index fece9c6844..15e3ea4e42 100644 --- a/src/market/MarketPlaceManagerDriver.cc +++ b/src/market/MarketPlaceManagerDriver.cc @@ -163,6 +163,37 @@ static void monitor_action( } } } + MarketPlaceApp *mp_app = nullptr; + std::string error; + std::string source; + int rc_del; + market = marketpool->get(id, true); + set apps_mp = market->get_marketapp_ids(); + market->unlock(); + + for (set::iterator i = apps_mp.begin(); i != apps_mp.end(); i++) { + mp_app = apppool->get(*i, true); + if ( mp_app != 0 ) + { + if(apppool->test_map_check(mp_app->get_name())){ //delete app + market = marketpool->get(id, true); + + source = mp_app->get_source(); + rc_del = apppool->drop(mp_app, error); + + market->del_marketapp(*i); + marketpool->update(market); + + market->unlock(); + if ( rc_del < 0 ) + { + oss << " Error removing app from DB: " << error + << ". Remove app manually, source is: " << source; + } + } + } + mp_app->unlock(); + } oss << "Marketplace " << name << " (" << id << ") successfully monitored."; From 0e1d5e42a9f10a5aba78dd833c2b78661f080f1a Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Fri, 14 Jul 2017 13:01:26 +0200 Subject: [PATCH 02/40] F #5245 Added datastore datatable in datastore requirements and solved bug in resources selected (#400) --- .../create/wizard-tabs/scheduling.js | 31 +++++++++++++++---- .../create/wizard-tabs/scheduling/html.hbs | 1 + 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js index e69fdcba83..88dbbfbe66 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js @@ -27,6 +27,7 @@ define(function(require) { var TemplateUtils = require('utils/template-utils'); var HostsTable = require('tabs/hosts-tab/datatable'); var ClustersTable = require('tabs/clusters-tab/datatable'); + var DatastoresTable = require('tabs/datastores-tab/datatable'); var UniqueId = require('utils/unique-id'); /* @@ -62,6 +63,7 @@ define(function(require) { } this.hostsTable = new HostsTable('HostsTable' + UniqueId.id(), options); this.clustersTable = new ClustersTable('ClustersTable' + UniqueId.id(), options); + this.datastoresTable = new DatastoresTable('DatastoresTable' + UniqueId.id(), options); } WizardTab.prototype.constructor = WizardTab; @@ -81,7 +83,8 @@ define(function(require) { function _html() { return TemplateHTML({ 'hostsTableSelectHTML': this.hostsTable.dataTableHTML, - 'clustersTableSelectHTML': this.clustersTable.dataTableHTML + 'clustersTableSelectHTML': this.clustersTable.dataTableHTML, + 'dsTableSelectHTML': this.datastoresTable.dataTableHTML }); } @@ -125,6 +128,8 @@ define(function(require) { that.hostsTable.refreshResourceTableSelect(); that.clustersTable.initialize(selectOptions); that.clustersTable.refreshResourceTableSelect(); + that.datastoresTable.initialize(selectOptions); + that.datastoresTable.refreshResourceTableSelect(); } function _retrieve(context) { @@ -132,7 +137,6 @@ define(function(require) { } function _fill(context, templateJSON) { - WizardFields.fill(context, templateJSON); var reqJSON = templateJSON['SCHED_REQUIREMENTS']; if (reqJSON) { @@ -163,16 +167,22 @@ define(function(require) { } this.clustersTable.selectResourceTableSelect(selectedResources); - - delete templateJSON['SCHED_REQUIREMENTS']; } var dsReqJSON = templateJSON['SCHED_DS_REQUIREMENTS']; if (dsReqJSON) { var dsReq = TemplateUtils.escapeDoubleQuotes(dsReqJSON); - delete templateJSON['SCHED_DS_REQUIREMENTS']; - } + var ds_id_regexp = /(\s|\||\b)ID=\\"([0-9]+)\\"/g; + var ds = []; + while (match = ds_id_regexp.exec(dsReq)) { + ds.push(match[2]) + } + var selectedResources = { + ids : ds + } + this.datastoresTable.selectResourceTableSelect(selectedResources); + } var rankJSON = templateJSON["SCHED_RANK"]; if (rankJSON) { @@ -207,12 +217,16 @@ define(function(require) { delete templateJSON["SCHED_DS_RANK"]; } + + WizardFields.fill(context, templateJSON); } function _generateRequirements(context) { var req_string=[]; + var req_ds_string=[]; var selected_hosts = this.hostsTable.retrieveResourceTableSelect(); var selected_clusters = this.clustersTable.retrieveResourceTableSelect(); + var selected_ds = this.datastoresTable.retrieveResourceTableSelect(); $.each(selected_hosts, function(index, hostId) { req_string.push('ID="'+hostId+'"'); @@ -222,6 +236,11 @@ define(function(require) { req_string.push('CLUSTER_ID="'+clusterId+'"'); }); + $.each(selected_ds, function(index, dsId) { + req_ds_string.push('ID="'+dsId+'"'); + }); + $('#SCHED_REQUIREMENTS', context).val(req_string.join(" | ")); + $('#SCHED_DS_REQUIREMENTS', context).val(req_ds_string.join(" | ")); }; }); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling/html.hbs index facadd26c0..a2d6453eae 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling/html.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling/html.hbs @@ -53,6 +53,7 @@
{{tr "Datastore Requirements"}} +
{{{dsTableSelectHTML}}}
diff --git a/src/sunstone/views/login.erb b/src/sunstone/views/login.erb index e3fbc081b0..21bc8a4c8e 100644 --- a/src/sunstone/views/login.erb +++ b/src/sunstone/views/login.erb @@ -28,7 +28,7 @@ <% end %>
+ +
+
+
+ + {{tr "Host"}} + +
{{{hostsDatatable}}}
+
+
+ + +
+
+
+
From 86f6dda9370046584e362da203c6a9cde9905e0d Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Mon, 17 Jul 2017 17:20:50 +0200 Subject: [PATCH 11/40] Simplify vCenter wild VM import code --- .../public/app/tabs/hosts-tab/panels/wilds.js | 283 ++---------------- src/sunstone/routes/vcenter.rb | 93 ------ 2 files changed, 31 insertions(+), 345 deletions(-) diff --git a/src/sunstone/public/app/tabs/hosts-tab/panels/wilds.js b/src/sunstone/public/app/tabs/hosts-tab/panels/wilds.js index 07cb6ab00f..1943ae32f4 100644 --- a/src/sunstone/public/app/tabs/hosts-tab/panels/wilds.js +++ b/src/sunstone/public/app/tabs/hosts-tab/panels/wilds.js @@ -68,193 +68,6 @@ define(function(require) { FUNCTION DEFINITIONS */ - function rollback_nics_and_disk(error_message, vmName, rollback_items, that, context, wild_row) { - var rollback_index = 0; - - function nextRollback() { - - if (rollback_items.length == rollback_index) { - var msg = Locale.tr("Could not import the wild VM " + vmName + " due to " + error_message + ". A rollback has been applied."); - Notifier.notifyError(msg); - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - - } else { - if (rollback_items[rollback_index].type === "NETWORK") { - var path = '/vcenter/network_rollback/' + rollback_items[rollback_index].id; - $.ajax({ - url: path, - type: "POST", - data: {timeout: false}, - dataType: "json", - success: function(response){ - ++rollback_index; - nextRollback(); - }, - error: function(response){ - var msg = OpenNebulaError(response).error.message; - Notifier.notifyError(msg); - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); } - }); - } - - if (rollback_items[rollback_index].type === "IMAGE") { - var path = '/vcenter/image_rollback/' + rollback_items[rollback_index].id; - $.ajax({ - url: path, - type: "POST", - data: {timeout: false}, - dataType: "json", - success: function(response){ - ++rollback_index; - nextRollback(); - }, - error: function(response){ - var msg = OpenNebulaError(response).error.message; - Notifier.notifyError(msg); - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - } - }); - } - } - } - - nextRollback(); - } - - - function import_images_and_nets(disks_and_nets, importHostId, vmName, that, context, wild_row) { - var index = 0; - var template = ""; - var rollback = []; - var duplicated_nics = {}; - - function getNext() { - - // Update the template - if (disks_and_nets.length == index) { - - // Create the VM in OpenNebula - var dataJSON = { - 'id': importHostId, - 'extra_param': { - 'name': vmName - } - }; - - OpenNebulaHost.import_wild({ - timeout: true, - data: dataJSON, - success: function(request, response) { - OpenNebulaAction.clear_cache("VM"); - Notifier.notifyCustom(Locale.tr("VM imported"), - Navigation.link(" ID: " + response.VM.ID, "vms-tab", response.VM.ID), - false); - - // Delete row (shouldn't be there in next monitorization) - that.dataTableWildHosts.fnDeleteRow(wild_row); - - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - }, - error: function (request, error_json) { - rollback_nics_and_disk(error_json.error.message, vmName, rollback, that, context, wild_row); - } - }); - - } else { - - if (disks_and_nets[index].type === "NEW_DISK") { - - var image_json = { - "image": { - "image_raw": disks_and_nets[index].image_tmpl - }, - "ds_id" : disks_and_nets[index].ds_id - }; - - OpenNebulaImage.create({ - timeout: true, - data: image_json, - success: function(request, response) { - var image_id = response.IMAGE.ID; - var image_uname = response.IMAGE.UNAME; - ++index; - var rollback_info = { type: "IMAGE", id: image_id}; - rollback.push(rollback_info); - getNext(); - }, - error: function (request, error_json) { - var error_message_str = error_json.error.message; - - // Rollback - var msg = (error_json.error.message || Locale.tr("Cannot contact server: is it running and reachable?")); - Notifier.notifyError(msg); - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - - rollback_nics_and_disk(error_json.error.message, vmName, rollback, that, context, wild_row); - } - }); - } - - if (disks_and_nets[index].type === "EXISTING_DISK") { - ++index; - getNext(); - } - - if (disks_and_nets[index].type === "NEW_NIC") { - - var vnet_json = { - "vnet": { - "vnet_raw": disks_and_nets[index].network_tmpl - } - }; - - var one_cluster_id = disks_and_nets[index].one_cluster_id; - - OpenNebulaNetwork.create({ - timeout: true, - data: vnet_json, - success: function(request, response) { - var network_id = response.VNET.ID; - if (one_cluster_id != -1) { - Sunstone.runAction("Cluster.addvnet",one_cluster_id,response.VNET.ID); - // Remove vnet from cluster default 0 - Sunstone.runAction("Cluster.delvnet",0,response.VNET.ID); - } - ++index; - var rollback_info = { type: "NETWORK", id: network_id}; - rollback.push(rollback_info); - getNext(); - }, - error: function (request, error_json) { - // Rollback - var msg = (error_json.error.message || Locale.tr("Cannot contact server: is it running and reachable?")); - Notifier.notifyError(msg); - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - - //rollback_nics_and_disk(error_json.error.message, template_id, rollback, row_context); - } - }); - } - - if (disks_and_nets[index].type == "EXISTING_NIC") { - ++index; - getNext(); - } - - if (disks_and_nets[index].type === "DUPLICATED_NIC") { - ++index; - getNext(); - } - } - } - getNext(); - } function _html() { return TemplateWilds(); @@ -332,78 +145,44 @@ define(function(require) { var aData = that.dataTableWildHosts.fnGetData(wild_row); var vmName = aData[1]; var remoteID = aData[2]; - if (remoteID.startsWith("vm-")) { - var path = '/vcenter/wild/' + remoteID; - $.ajax({ - url: path, - type: "GET", - data: {timeout: false}, - headers: { - "X-VCENTER-USER": that.element.TEMPLATE.VCENTER_USER, - "X-VCENTER-PASSWORD": that.element.TEMPLATE.VCENTER_PASSWORD, - "X-VCENTER-HOST": that.element.TEMPLATE.VCENTER_HOST - }, - dataType: "json", - success: function(response){ - var disks_and_nets = response.disks.concat(response.nics) - import_images_and_nets(disks_and_nets, importHostId, vmName, that, context, wild_row); - }, - error: function(response){ - var msg; - if (response.responseJSON && response.responseJSON.error.message){ - msg = response.responseJSON.error.message; - } else { - msg = Locale.tr("Cannot contact server: is it running and reachable?"); - } + var dataJSON = { + 'id': importHostId, + 'extra_param': { + 'name': vmName + } + }; - Notifier.notifyError(msg); + // Create the VM in OpenNebula + OpenNebulaHost.import_wild({ + timeout: true, + data: dataJSON, + success: function(request, response) { + OpenNebulaAction.clear_cache("VM"); + Notifier.notifyCustom(Locale.tr("VM imported"), + Navigation.link(" ID: " + response.VM.ID, "vms-tab", response.VM.ID), + false); - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - } - }); + // Delete row (shouldn't be there in next monitorization) + that.dataTableWildHosts.fnDeleteRow(wild_row); - } else { - - var dataJSON = { - 'id': importHostId, - 'extra_param': { - 'name': vmName + $("#import_wilds", context).removeAttr("disabled").off("click.disable"); + $("#import_wilds", context).html(Locale.tr("Import Wilds")); + }, + error: function (request, error_json) { + var msg; + if (error_json.error.message){ + msg = error_json.error.message; + } else { + msg = Locale.tr("Cannot contact server: is it running and reachable?"); } - }; - // Create the VM in OpenNebula - OpenNebulaHost.import_wild({ - timeout: true, - data: dataJSON, - success: function(request, response) { - OpenNebulaAction.clear_cache("VM"); - Notifier.notifyCustom(Locale.tr("VM imported"), - Navigation.link(" ID: " + response.VM.ID, "vms-tab", response.VM.ID), - false); + Notifier.notifyError(msg); - // Delete row (shouldn't be there in next monitorization) - that.dataTableWildHosts.fnDeleteRow(wild_row); - - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - }, - error: function (request, error_json) { - var msg; - if (error_json.error.message){ - msg = error_json.error.message; - } else { - msg = Locale.tr("Cannot contact server: is it running and reachable?"); - } - - Notifier.notifyError(msg); - - $("#import_wilds", context).removeAttr("disabled").off("click.disable"); - $("#import_wilds", context).html(Locale.tr("Import Wilds")); - } - }); - } + $("#import_wilds", context).removeAttr("disabled").off("click.disable"); + $("#import_wilds", context).html(Locale.tr("Import Wilds")); + } + }); }); }); diff --git a/src/sunstone/routes/vcenter.rb b/src/sunstone/routes/vcenter.rb index adcb5a2588..f19bb5f5a2 100644 --- a/src/sunstone/routes/vcenter.rb +++ b/src/sunstone/routes/vcenter.rb @@ -397,99 +397,6 @@ get '/vcenter/template/:vcenter_ref/:template_id' do end end -get '/vcenter/wild/:vcenter_ref' do - begin - t = {} - template = nil - vm_ref = params[:vcenter_ref] - sunstone = true - wild = true - - if !vm_ref || vm_ref.empty? - msg = "No VM moref for Wild VM specified" - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - vc_uuid = vcenter_client.vim.serviceContent.about.instanceUuid - - dpool = VCenterDriver::VIHelper.one_pool(OpenNebula::DatastorePool) - if dpool.respond_to?(:message) - msg = "Could not get OpenNebula DatastorePool: #{dpool.message}" - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - ipool = VCenterDriver::VIHelper.one_pool(OpenNebula::ImagePool) - if ipool.respond_to?(:message) - msg = "Could not get OpenNebula ImagePool: #{ipool.message}" - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - npool = VCenterDriver::VIHelper.one_pool(OpenNebula::VirtualNetworkPool) - if npool.respond_to?(:message) - msg = "Could not get OpenNebula VirtualNetworkPool: #{npool.message}" - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - hpool = VCenterDriver::VIHelper.one_pool(OpenNebula::HostPool) - if hpool.respond_to?(:message) - msg = "Could not get OpenNebula HostPool: #{hpool.message}" - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - vcenter_vm = VCenterDriver::VirtualMachine.new_from_ref(vm_ref, vcenter_client) - vm_name = vcenter_vm["name"] - - # Get disks information for template - error, template_disks = vcenter_vm.import_vcenter_disks(vc_uuid, dpool, ipool, sunstone) - - if !error.empty? - msg = error - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - t[:disks] = template_disks - - # Get nics information for template - - # Create images or get nics information for template - error, template_nics = vcenter_vm.import_vcenter_nics(vc_uuid, - npool, - hpool, - vcenter_client.vim.host, - vm_ref, - wild, - sunstone, - vm_name) - - if !error.empty? - msg = error - logger.error("[vCenter] " + msg) - error = Error.new(msg) - error 404, error.to_json - end - - t[:nics] = template_nics - - [200, t.to_json] - rescue Exception => e - logger.error("[vCenter] " + e.message) - error = Error.new(e.message) - error 403, error.to_json - end -end - get '/vcenter/networks' do begin dc_folder = VCenterDriver::DatacenterFolder.new(vcenter_client) From 221ce1c64b5d491ce5fc7e49055f32eb0778e330 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Thu, 13 Jul 2017 16:36:05 +0200 Subject: [PATCH 12/40] Do not delete VLAN_ID from inside ARs --- src/onedb/local/4.13.85_to_4.90.0.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onedb/local/4.13.85_to_4.90.0.rb b/src/onedb/local/4.13.85_to_4.90.0.rb index c748b1466f..ea8c5f53fe 100644 --- a/src/onedb/local/4.13.85_to_4.90.0.rb +++ b/src/onedb/local/4.13.85_to_4.90.0.rb @@ -762,7 +762,7 @@ module Migrator reserved_vlan_ids << vlan_id end - doc.root.xpath('//VLAN_ID').remove + doc.root.xpath("//VLAN_ID[not(parent::AR)]").each {|e| e.remove } end doc.root.add_child(doc.create_element("VLAN_ID")).content = vlan_id From e243c86b1c90f117e81aa7be84fa20b403a7bbd2 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 17 Jul 2017 08:25:28 +0200 Subject: [PATCH 13/40] F #4913: Do not discover unmanaged nics/disks --- src/onedb/vcenter_one54_pre.rb | 504 +++++++++++++++++---------------- 1 file changed, 261 insertions(+), 243 deletions(-) diff --git a/src/onedb/vcenter_one54_pre.rb b/src/onedb/vcenter_one54_pre.rb index 533bc1d46b..3076c22a47 100644 --- a/src/onedb/vcenter_one54_pre.rb +++ b/src/onedb/vcenter_one54_pre.rb @@ -16,16 +16,14 @@ # limitations under the License. # #--------------------------------------------------------------------------- # -#!/usr/bin/env ruby - -ONE_LOCATION=ENV["ONE_LOCATION"] +ONE_LOCATION = ENV["ONE_LOCATION"] if !ONE_LOCATION - RUBY_LIB_LOCATION="/usr/lib/one/ruby" - REMOTES_LOCATION="/var/lib/one/remotes/" + RUBY_LIB_LOCATION = "/usr/lib/one/ruby" + REMOTES_LOCATION = "/var/lib/one/remotes/" else - RUBY_LIB_LOCATION=ONE_LOCATION+"/lib/ruby" - REMOTES_LOCATION=ONE_LOCATION+"/var/remotes/" + RUBY_LIB_LOCATION = ONE_LOCATION+"/lib/ruby" + REMOTES_LOCATION = ONE_LOCATION+"/var/remotes/" end $: << RUBY_LIB_LOCATION @@ -41,6 +39,7 @@ require 'vcenter_driver' require 'opennebula' TEMP_DIR="/var/tmp/vcenter_one54" + FileUtils.mkdir_p TEMP_DIR def banner(msg, header=false, extended=nil) @@ -257,6 +256,7 @@ def create_system_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, dc_name, dc_re raise rc.message if OpenNebula.is_error?(rc) STDOUT.puts "Datastore \e[96m#{ds_name}\e[39m is now also a SYSTEM datastore with ID: #{one_ds["ID"]}\n" + one_ds end def get_dc(item) @@ -362,124 +362,98 @@ def vm_unmanaged_discover(devices, xml_doc, template_xml, cluster_id = one_clusters[host_id] - devices.each do |device| - rc = vnpool.info_all - raise "\n ERROR! Could not update vnpool. Reason #{rc.message}" if OpenNebula.is_error?(rc) + if !vm_wild && template_xml + devices.each do |device| + rc = vnpool.info_all + raise "\n ERROR! Could not update vnpool. Reason #{rc.message}" if OpenNebula.is_error?(rc) - rc = ipool.info_all - raise "\n ERROR! Could not update ipool. Reason #{rc.message}" if OpenNebula.is_error?(rc) + rc = ipool.info_all + raise "\n ERROR! Could not update ipool. Reason #{rc.message}" if OpenNebula.is_error?(rc) - rc = dspool.info - raise "\n ERROR! Could not update dspool. Reason #{rc.message}" if OpenNebula.is_error?(rc) + rc = dspool.info + raise "\n ERROR! Could not update dspool. Reason #{rc.message}" if OpenNebula.is_error?(rc) - if defined?(RbVmomi::VIM::VirtualIDEController) && - device.is_a?(RbVmomi::VIM::VirtualIDEController) - ide_controlled += device.device - next - end - - if defined?(RbVmomi::VIM::VirtualSATAController) && - device.is_a?(RbVmomi::VIM::VirtualSATAController) - sata_controlled += device.device - next - end - - if defined?(RbVmomi::VIM::VirtualSCSIController) && - device.is_a?(RbVmomi::VIM::VirtualSCSIController) - scsi_controlled += device.device - next - end - - #cluster_id = xml_doc.root.xpath("HISTORY_RECORDS/HISTORY[last()]/CID").text - - # If CDROM - if !(device.class.ancestors.index(RbVmomi::VIM::VirtualCdrom)).nil? - ds_name = device.backing.datastore.name - ds_ref = device.backing.datastore._ref - image_path = device.backing.fileName.sub(/^\[(.*?)\] /, "") - - image = find_image(ipool, ds_name, image_path) - - if image - # It's a persistent disk if it already exists - xml_template = xml_doc.root.at_xpath("TEMPLATE") - existing_disk = existing_disks[managed_disk_index] - - # Replace DISK_ID - existind_disk_id = existing_disk.at_xpath("DISK_ID") - existind_disk_id.content = disk_index - - disk = xml_template.add_child(existing_disks[managed_disk_index]) - - # Add VCENTER_DS_REF - disk.add_child(xml_doc.create_element("VCENTER_DS_REF")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{ds_ref}")) - - STDOUT.puts "--- Added VCENTER_DS_REF=#{ds_ref} to CDROM (IMAGE_ID=#{image["ID"]})" - - # Update indexes - managed_disk_index = managed_disk_index + 1 - disk_index = disk_index + 1 + if defined?(RbVmomi::VIM::VirtualIDEController) && + device.is_a?(RbVmomi::VIM::VirtualIDEController) + ide_controlled += device.device + next end - end - # If Virtual Disk - if !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil? - ds_name = device.backing.datastore.name - ds_ref = device.backing.datastore._ref - image_type = "OS" - image_path = device.backing.fileName.sub(/^\[(.*?)\] /, "") - image_prefix = "hd" if ide_controlled.include?(device.key) - image_prefix = "sd" if scsi_controlled.include?(device.key) - image_prefix = "sd" if sata_controlled.include?(device.key) - file_name = File.basename(image_path).gsub(/\.vmdk$/,"") - image_name = "#{file_name} - #{ds_name}" + if defined?(RbVmomi::VIM::VirtualSATAController) && + device.is_a?(RbVmomi::VIM::VirtualSATAController) + sata_controlled += device.device + next + end - #Check if the image already exists - one_image = find_image(ipool, ds_name, image_path) + if defined?(RbVmomi::VIM::VirtualSCSIController) && + device.is_a?(RbVmomi::VIM::VirtualSCSIController) + scsi_controlled += device.device + next + end - if !one_image - #Check if the IMAGE DS is there - ds = find_datastore(dspool, ds_ref, dc_ref, vcenter_uuid, "IMAGE_DS") + #cluster_id = xml_doc.root.xpath("HISTORY_RECORDS/HISTORY[last()]/CID").text - #Create IMAGE and SYSTEM DS if datastore is not found - if !ds - ds = create_image_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, ccr_name, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) + # If CDROM + if !(device.class.ancestors.index(RbVmomi::VIM::VirtualCdrom)).nil? + device_backing_datastore = device.backing.datastore rescue nil + if device_backing_datastore + ds_name = device.backing.datastore.name + ds_ref = device.backing.datastore._ref + image_path = device.backing.fileName.sub(/^\[(.*?)\] /, "") - create_system_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) + image = find_image(ipool, ds_name, image_path) + + if image + # It's a persistent disk if it already exists + xml_template = xml_doc.root.at_xpath("TEMPLATE") + existing_disk = existing_disks[managed_disk_index] + + # Replace DISK_ID + existind_disk_id = existing_disk.at_xpath("DISK_ID") + existind_disk_id.content = disk_index + + disk = xml_template.add_child(existing_disks[managed_disk_index]) + + # Add VCENTER_DS_REF + disk.add_child(xml_doc.create_element("VCENTER_DS_REF")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{ds_ref}")) + + STDOUT.puts "--- Added VCENTER_DS_REF=#{ds_ref} to CDROM (IMAGE_ID=#{image["ID"]})" + + # Update indexes + managed_disk_index = managed_disk_index + 1 + disk_index = disk_index + 1 + end end + end - ds_id = ds["ID"].to_i + # If Virtual Disk + if !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil? + ds_name = device.backing.datastore.name + ds_ref = device.backing.datastore._ref + image_type = "OS" + image_path = device.backing.fileName.sub(/^\[(.*?)\] /, "") + image_prefix = "hd" if ide_controlled.include?(device.key) + image_prefix = "sd" if scsi_controlled.include?(device.key) + image_prefix = "sd" if sata_controlled.include?(device.key) + file_name = File.basename(image_path).gsub(/\.vmdk$/,"") + image_name = "#{file_name} - #{ds_name}" - if vm_wild || !template_xml - #Create images for unmanaged disks + #Check if the image already exists + one_image = find_image(ipool, ds_name, image_path) - template = "" - template << "NAME=\"#{image_name}\"\n" - template << "PATH=\"vcenter://#{image_path}\"\n" - template << "TYPE=\"#{image_type}\"\n" - template << "PERSISTENT=\"NO\"\n" - template << "VCENTER_IMPORTED=\"YES\"\n" - template << "DEV_PREFIX=\"#{image_prefix}\"\n" + if !one_image + #Check if the IMAGE DS is there + ds = find_datastore(dspool, ds_ref, dc_ref, vcenter_uuid, "IMAGE_DS") - one_image = OpenNebula::Image.new(OpenNebula::Image.build_xml, one_client) - rc = one_image.allocate(template, ds_id) - raise "\n ERROR! Could not create image for wild vm. Reason #{rc.message}" if OpenNebula.is_error?(rc) + #Create IMAGE and SYSTEM DS if datastore is not found + if !ds + ds = create_image_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, ccr_name, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) - loop do - rc = one_image.info - raise "\n ERROR! Could not get image info for wild vm disk. Reason #{rc.message}" if OpenNebula.is_error?(rc) - break if one_image["SOURCE"] && !one_image["SOURCE"].empty? #Get out of loop if image is not locked - sleep(1) + create_system_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) end - if one_image["STATE"] == 5 - raise "\n ERROR! The image created for wild vm is in ERROR state" - end + ds_id = ds["ID"].to_i - vcenter_ids[:image] << one_image["ID"] - - STDOUT.puts "--- Image #{one_image["NAME"]} with ID #{one_image["ID"]} has been created" - else template_disk = template_xml.xpath("VMTEMPLATE/TEMPLATE/DISK")[unmanaged_disk_index] rescue nil raise "Cannot find unmanaged disk inside template" if !template_disk @@ -499,165 +473,165 @@ def vm_unmanaged_discover(devices, xml_doc, template_xml, ds_name = ds["NAME"] STDOUT.puts "--- Image #{one_image["NAME"]} with ID #{one_image["ID"]} already exists" - end - # Create unmanaged disk element for vm template - # Get disk size (capacity) - image_name = one_image["NAME"] - image_source = one_image["SOURCE"] - image_id = one_image["ID"] - - # Add new disk attributes - create_disk(xml_doc, image_name, image_source, image_prefix, image_id, - disk_index, cluster_id, ds, ds_ref, ds_name, vi_client) - - STDOUT.puts "--- Added unmanaged disk to xml template (IMAGE_ID=#{one_image["ID"]})" - - reference = {} - reference[:key] = "opennebula.disk.#{unmanaged_disk_index}" - reference[:value] = "#{device.key}" - extraconfig << reference - - unmanaged_disk_index = unmanaged_disk_index + 1 - disk_index = disk_index + 1 - else - - if one_image["TEMPLATE/VCENTER_IMPORTED"] == "YES" - - #Check if the IMAGE DS is there - ds = find_datastore(dspool, ds_ref, dc_ref, vcenter_uuid, "IMAGE_DS") - - #Create IMAGE and SYSTEM DS if datastore is not found - if !ds - ds = create_image_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, ccr_name, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) - - create_system_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) - end - - ds_id = ds["ID"].to_i - - #Create unmanaged disk element for vm template - image_id = one_image["ID"] + # Create unmanaged disk element for vm template + # Get disk size (capacity) image_name = one_image["NAME"] image_source = one_image["SOURCE"] + image_id = one_image["ID"] + # Add new disk attributes create_disk(xml_doc, image_name, image_source, image_prefix, image_id, disk_index, cluster_id, ds, ds_ref, ds_name, vi_client) - STDOUT.puts "--- Added unmanaged disk in wild vm (IMAGE_ID=#{one_image["ID"]})" + STDOUT.puts "--- Added unmanaged disk to xml template (IMAGE_ID=#{one_image["ID"]})" reference = {} reference[:key] = "opennebula.disk.#{unmanaged_disk_index}" reference[:value] = "#{device.key}" extraconfig << reference - # Update indexes unmanaged_disk_index = unmanaged_disk_index + 1 disk_index = disk_index + 1 - else - # It's a persistent disk if it already exists - xml_template = xml_doc.root.at_xpath("TEMPLATE") - existing_disk = existing_disks[managed_disk_index] + if one_image["TEMPLATE/VCENTER_IMPORTED"] == "YES" + # This is (probably) a wild VM. The code should not reach this. - # Replace DISK_ID - existing_disk_image_id = existing_disk.xpath("IMAGE_ID").text - existing_disk_id = existing_disk.at_xpath("DISK_ID") - existing_disk_id.content = disk_index + #Check if the IMAGE DS is there + ds = find_datastore(dspool, ds_ref, dc_ref, vcenter_uuid, "IMAGE_DS") - disk = xml_template.add_child(existing_disks[managed_disk_index]) + #Create IMAGE and SYSTEM DS if datastore is not found + if !ds + ds = create_image_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, ccr_name, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) - # Add VCENTER_DISK_TYPE and VCENTER_ADAPTER_TYPE if found - if !existing_disk.xpath("DISK_TYPE").text.empty? - disk.add_child(xml_doc.create_element("VCENTER_DISK_TYPE")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{existing_disk.xpath("DISK_TYPE").text}")) - STDOUT.puts "--- Added VCENTER_DISK_TYPE=#{existing_disk.xpath("DISK_TYPE").text} to existing disk (IMAGE_ID=#{existing_disk_image_id})" + create_system_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) + end + + ds_id = ds["ID"].to_i + + #Create unmanaged disk element for vm template + image_id = one_image["ID"] + image_name = one_image["NAME"] + image_source = one_image["SOURCE"] + + create_disk(xml_doc, image_name, image_source, image_prefix, image_id, + disk_index, cluster_id, ds, ds_ref, ds_name, vi_client) + + STDOUT.puts "--- Added unmanaged disk in wild vm (IMAGE_ID=#{one_image["ID"]})" + + reference = {} + reference[:key] = "opennebula.disk.#{unmanaged_disk_index}" + reference[:value] = "#{device.key}" + extraconfig << reference + + # Update indexes + unmanaged_disk_index = unmanaged_disk_index + 1 + disk_index = disk_index + 1 + + else + # It's a persistent disk if it already exists + xml_template = xml_doc.root.at_xpath("TEMPLATE") + existing_disk = existing_disks[managed_disk_index] + + # Replace DISK_ID + existing_disk_image_id = existing_disk.xpath("IMAGE_ID").text + existing_disk_id = existing_disk.at_xpath("DISK_ID") + existing_disk_id.content = disk_index + + disk = xml_template.add_child(existing_disks[managed_disk_index]) + + # Add VCENTER_DISK_TYPE and VCENTER_ADAPTER_TYPE if found + if !existing_disk.xpath("DISK_TYPE").text.empty? + disk.add_child(xml_doc.create_element("VCENTER_DISK_TYPE")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{existing_disk.xpath("DISK_TYPE").text}")) + STDOUT.puts "--- Added VCENTER_DISK_TYPE=#{existing_disk.xpath("DISK_TYPE").text} to existing disk (IMAGE_ID=#{existing_disk_image_id})" + end + + if !existing_disk.xpath("ADAPTER_TYPE").text.empty? + disk.add_child(xml_doc.create_element("VCENTER_ADAPTER_TYPE")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{existing_disk.xpath("ADAPTER_TYPE").text}")) + STDOUT.puts "--- Added VCENTER_ADAPTER_TYPE=#{existing_disk.xpath("ADAPTER_TYPE").text} to existing disk (IMAGE_ID=#{existing_disk_image_id})" + end + + # Add VCENTER_DS_REF + disk.add_child(xml_doc.create_element("VCENTER_DS_REF")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{ds_ref}")) + STDOUT.puts "--- Added VCENTER_DS_REF=#{ds_ref} to existing disk (IMAGE_ID=#{existing_disk_image_id})" + + # Update indexes + managed_disk_index = managed_disk_index + 1 + disk_index = disk_index + 1 end - - if !existing_disk.xpath("ADAPTER_TYPE").text.empty? - disk.add_child(xml_doc.create_element("VCENTER_ADAPTER_TYPE")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{existing_disk.xpath("ADAPTER_TYPE").text}")) - STDOUT.puts "--- Added VCENTER_ADAPTER_TYPE=#{existing_disk.xpath("ADAPTER_TYPE").text} to existing disk (IMAGE_ID=#{existing_disk_image_id})" - end - - # Add VCENTER_DS_REF - disk.add_child(xml_doc.create_element("VCENTER_DS_REF")).add_child(Nokogiri::XML::CDATA.new(xml_doc,"#{ds_ref}")) - STDOUT.puts "--- Added VCENTER_DS_REF=#{ds_ref} to existing disk (IMAGE_ID=#{existing_disk_image_id})" - - # Update indexes - managed_disk_index = managed_disk_index + 1 - disk_index = disk_index + 1 end end - end - # If VirtualEthernetCard - if !device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil? - network_bridge = device.backing.network.name - network_ref = device.backing.network._ref - network_name = "#{network_bridge} [#{vm_name}]" - network_type = device.backing.network.instance_of?(RbVmomi::VIM::DistributedVirtualPortgroup) ? "Distributed Port Group" : "Port Group" + # If VirtualEthernetCard + if !device.class.ancestors.index(RbVmomi::VIM::VirtualEthernetCard).nil? + network_bridge = device.backing.network.name + network_ref = device.backing.network._ref + network_name = "#{network_bridge} [#{vm_name}]" + network_type = device.backing.network.instance_of?(RbVmomi::VIM::DistributedVirtualPortgroup) ? "Distributed Port Group" : "Port Group" - # Create network if doesn't exist - network = find_network(vnpool, network_ref, ccr_ref, template_ref, vcenter_uuid) + # Create network if doesn't exist + network = find_network(vnpool, network_ref, ccr_ref, template_ref, vcenter_uuid) - if !network - one_net = "" - one_net << "NAME=\"#{network_name}\"\n" - one_net << "BRIDGE=\"#{network_bridge}\"\n" - one_net << "VN_MAD=\"dummy\"\n" - one_net << "VCENTER_PORTGROUP_TYPE=\"#{network_type}\"\n" - one_net << "VCENTER_NET_REF=\"#{network_ref}\"\n" - one_net << "VCENTER_CCR_REF=\"#{ccr_ref}\"\n" - one_net << "VCENTER_INSTANCE_ID=\"#{vcenter_uuid}\"\n" - one_net << "VCENTER_TEMPLATE_REF=\"#{template_ref}\"\n" - one_net << "OPENNEBULA_MANAGED=\"NO\"\n" - one_net << "AR=[\n" - one_net << "TYPE=\"ETHER\",\n" - one_net << "SIZE=\"255\"\n" - one_net << "]\n" + if !network + one_net = "" + one_net << "NAME=\"#{network_name}\"\n" + one_net << "BRIDGE=\"#{network_bridge}\"\n" + one_net << "VN_MAD=\"dummy\"\n" + one_net << "VCENTER_PORTGROUP_TYPE=\"#{network_type}\"\n" + one_net << "VCENTER_NET_REF=\"#{network_ref}\"\n" + one_net << "VCENTER_CCR_REF=\"#{ccr_ref}\"\n" + one_net << "VCENTER_INSTANCE_ID=\"#{vcenter_uuid}\"\n" + one_net << "VCENTER_TEMPLATE_REF=\"#{template_ref}\"\n" + one_net << "OPENNEBULA_MANAGED=\"NO\"\n" + one_net << "AR=[\n" + one_net << "TYPE=\"ETHER\",\n" + one_net << "SIZE=\"255\"\n" + one_net << "]\n" - one_vn = OpenNebula::VirtualNetwork.new(OpenNebula::VirtualNetwork.build_xml, one_client) - rc = one_vn.allocate(one_net, cluster_id.to_i) - raise "\n ERROR! Could not create vnet for vm #{vm_name}. Reason #{rc.message}" if OpenNebula.is_error?(rc) + one_vn = OpenNebula::VirtualNetwork.new(OpenNebula::VirtualNetwork.build_xml, one_client) + rc = one_vn.allocate(one_net, cluster_id.to_i) + raise "\n ERROR! Could not create vnet for vm #{vm_name}. Reason #{rc.message}" if OpenNebula.is_error?(rc) - rc = one_vn.info - raise "\n ERROR! Could not get network info for vnet #{network_name}. Reason #{rc.message}" if OpenNebula.is_error?(rc) - network = one_vn - STDOUT.puts "--- Network #{one_vn["NAME"]} with ID #{one_vn["ID"]} has been created" - else - STDOUT.puts "--- Network #{network["NAME"]} with ID #{network["ID"]} already exists" - end + rc = one_vn.info + raise "\n ERROR! Could not get network info for vnet #{network_name}. Reason #{rc.message}" if OpenNebula.is_error?(rc) + network = one_vn + STDOUT.puts "--- Network #{one_vn["NAME"]} with ID #{one_vn["ID"]} has been created" + else + STDOUT.puts "--- Network #{network["NAME"]} with ID #{network["ID"]} already exists" + end - existing_macs = [] - existing_nics.xpath("MAC").each do |mac| - existing_macs << mac.text - end + existing_macs = [] + existing_nics.xpath("MAC").each do |mac| + existing_macs << mac.text + end - mac_address = device.macAddress - if !existing_macs.include?(mac_address) - # Unmanaged nic - create_nic(xml_doc, network, mac_address, cluster_id, nic_index) + mac_address = device.macAddress + if !existing_macs.include?(mac_address) + # Unmanaged nic + create_nic(xml_doc, network, mac_address, cluster_id, nic_index) - #Update indexes - nic_index = nic_index + 1 - else - # Managed nic - managed_nic_index = existing_macs.index(mac_address) - xml_template = xml_doc.root.at_xpath("TEMPLATE") - existing_nic = existing_nics[managed_nic_index] + #Update indexes + nic_index = nic_index + 1 + else + # Managed nic + managed_nic_index = existing_macs.index(mac_address) + xml_template = xml_doc.root.at_xpath("TEMPLATE") + existing_nic = existing_nics[managed_nic_index] - # Replace NIC_ID - existind_nic_id = existing_nic.at_xpath("NIC_ID") - existind_nic_id.content = nic_index + # Replace NIC_ID + existind_nic_id = existing_nic.at_xpath("NIC_ID") + existind_nic_id.content = nic_index - # Add existing NIC to XML template - nic = xml_template.add_child(existing_nics[managed_nic_index]) - create_cdata_element(nic, xml_doc, "VCENTER_NET_REF", "#{network["TEMPLATE/VCENTER_NET_REF"]}") - create_cdata_element(nic, xml_doc, "VCENTER_CCR_REF", "#{network["TEMPLATE/VCENTER_CCR_REF"]}") - create_cdata_element(nic, xml_doc, "VCENTER_INSTANCE_ID", "#{network["TEMPLATE/VCENTER_INSTANCE_ID"]}") - create_cdata_element(nic, xml_doc, "VCENTER_PORTGROUP_TYPE", "#{network["TEMPLATE/VCENTER_PORTGROUP_TYPE"]}") + # Add existing NIC to XML template + nic = xml_template.add_child(existing_nics[managed_nic_index]) + create_cdata_element(nic, xml_doc, "VCENTER_NET_REF", "#{network["TEMPLATE/VCENTER_NET_REF"]}") + create_cdata_element(nic, xml_doc, "VCENTER_CCR_REF", "#{network["TEMPLATE/VCENTER_CCR_REF"]}") + create_cdata_element(nic, xml_doc, "VCENTER_INSTANCE_ID", "#{network["TEMPLATE/VCENTER_INSTANCE_ID"]}") + create_cdata_element(nic, xml_doc, "VCENTER_PORTGROUP_TYPE", "#{network["TEMPLATE/VCENTER_PORTGROUP_TYPE"]}") - #Update indexes - nic_index = nic_index + 1 + #Update indexes + nic_index = nic_index + 1 + end end end end @@ -716,10 +690,16 @@ def vm_unmanaged_discover(devices, xml_doc, template_xml, if !vc_vmachines.key? vm_ref raise "Could not find vcenter vm using ref #{vm_ref} in order to assign a datastore" else - ds_ref = vc_vmachines[vm_ref]["datastore"].first._ref rescue nil - raise "Could not get ds ref in order to assign a datastore in history records" if !ds_ref + vc_system_ds = vc_vmachine["datastore"].first rescue nil + raise "Could not find Datastore associated with the VM" if vc_system_ds.nil? + + ds_ref = vc_system_ds._ref ds = find_datastore(dspool, ds_ref, dc_ref, vcenter_uuid, "SYSTEM_DS") + if !ds + ds_name = vc_system_ds.name + ds = create_system_ds(ds_name, ds_ref, vcenter_name, vcenter_uuid, dc_name, dc_ref, one_client, vcenter_user, vcenter_pass, vcenter_host, cluster_id) + end ds_id = ds["ID"] end else @@ -2101,13 +2081,15 @@ def inspect_templates(vc_templates, vc_clusters, one_clusters, tpool, ipool, vnp end end - # Try to get moref using the templates uuid note that that uuid + # Try to get moref using the templates uuid. Note that that uuid # is not unique + templates_same_uuid = {} if !template_ref && template_uuid templates_found = 0 vc_templates[vcenter_uuid].each do |ref, value| if value["config.uuid"] == template_uuid templates_found += 1 + templates_same_uuid[ref] = value if templates_found > 1 template_ref = nil else @@ -2125,7 +2107,14 @@ def inspect_templates(vc_templates, vc_clusters, one_clusters, tpool, ipool, vnp index = 0 template_refs = [] - vc_templates[vcenter_uuid].each do |ref, t| + if templates_same_uuid.length > 1 + # Choose only between those that have the same UUID + templates_list = templates_same_uuid + else + templates_list = vc_templates[vcenter_uuid] + end + + templates_list.each do |ref, t| item = RbVmomi::VIM::VirtualMachine.new(vi_client.vim, ref) folders = [] @@ -2165,15 +2154,33 @@ def inspect_templates(vc_templates, vc_clusters, one_clusters, tpool, ipool, vnp STDOUT.puts "-" * 80 end + # Get OpenNebulas's template + one_template = OpenNebula::Template.new_with_id(template["ID"], one_client) STDOUT.puts if !template_ref - raise "Template #{template_name} could not be updated, cannot find template's MOREF" + STDOUT.print "Could not upgrade this template. Not found in vCenter. Do you want to remove it? (y/n) " + loop do + option = STDIN.gets.strip + case option + when "y" + # delete + rc = one_template.delete + raise "Template #{template["ID"]}: '#{template["NAME"]}' could not be deleted. Reason #{rc.message}" if OpenNebula.is_error?(rc) + + STDOUT.puts("\nTemplate #{template["ID"]}: '#{template["NAME"]}' has been \e[93mdeleted\e[39m.") + break + when "n" + STDOUT.puts("\nTemplate #{template["ID"]}: '#{template["NAME"]}' is \e[93mbroken\e[39m. Please inspect it manually after the upgrade.") + STDOUT.puts("\nPress any key to continue.\n") + STDIN.gets + break + end + end + next end - # Get OpenNebulas's template - one_template = OpenNebula::Template.new_with_id(template["ID"], one_client) - rc = one_template.info + rc = one_template.info raise "Could not get info for template #{template["ID"]}. Reason: #{rc.message}" if OpenNebula.is_error?(rc) # Find vcenter template in vc_templates @@ -2372,8 +2379,10 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i # Refresh pools rc = vnpool.info_all raise "\n ERROR! Could not update vnpool. Reason #{rc.message}" if OpenNebula.is_error?(rc) + rc = ipool.info_all raise "\n ERROR! Could not update ipool. Reason #{rc.message}" if OpenNebula.is_error?(rc) + rc = dspool.info raise "\n ERROR! Could not update dspool. Reason #{rc.message}" if OpenNebula.is_error?(rc) @@ -2498,11 +2507,13 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i # Try to get moref using the templates uuid note that that uuid # is not unique + templates_same_uuid = {} if !template_ref && template_uuid templates_found = 0 vc_templates[vcenter_uuid].each do |ref, value| if value["config.uuid"] == template_uuid templates_found += 1 + templates_same_uuid[ref] = value if templates_found > 1 template_ref = nil else @@ -2520,7 +2531,14 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i index = 0 template_refs = [] - vc_templates[vcenter_uuid].each do |ref, t| + if templates_same_uuid.length > 1 + # Choose only between those that have the same UUID + templates_list = templates_same_uuid + else + templates_list = vc_templates[vcenter_uuid] + end + + templates_list.each do |ref, t| item = RbVmomi::VIM::VirtualMachine.new(vi_client.vim, ref) folders = [] @@ -2772,7 +2790,7 @@ CommandParser::CmdParser.new(ARGV) do vc_clusters[vcenter_uuid] = retrieve_vcenter_clusters(vi_client) vc_datastores[vcenter_uuid] = retrieve_vcenter_datastores(vi_client) vc_networks[vcenter_uuid] = retrieve_vcenter_networks(vi_client) - vc_vmachines[vcenter_uuid], vc_templates[vcenter_uuid] = retrieve_vcenter_vms(vi_client) + vc_vmachines[vcenter_uuid], vc_templates[vcenter_uuid] = retrieve_vcenter_vms(vi_client) STDOUT.puts "--- #{host["TEMPLATE/VCENTER_HOST"]} \e[92mobjects have been retrieved\e[39m" end From dd97208ca36de5df81823bf1fe2434cc7050b268 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 17 Jul 2017 08:28:43 +0200 Subject: [PATCH 14/40] Remove specific vCenter deploy action --- src/oca/ruby/opennebula/virtual_machine.rb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/oca/ruby/opennebula/virtual_machine.rb b/src/oca/ruby/opennebula/virtual_machine.rb index 060bd70923..f7b4de9167 100644 --- a/src/oca/ruby/opennebula/virtual_machine.rb +++ b/src/oca/ruby/opennebula/virtual_machine.rb @@ -14,7 +14,6 @@ # limitations under the License. # #--------------------------------------------------------------------------- # - require 'opennebula/pool_element' module OpenNebula @@ -343,16 +342,6 @@ module OpenNebula self.info - # Add dsid as VM template parameter for vcenter - if ds_id!=-1 && - !self["/VM/USER_TEMPLATE/PUBLIC_CLOUD/TYPE"].nil? && - self["/VM/USER_TEMPLATE/PUBLIC_CLOUD/TYPE"].downcase == "vcenter" - ds = OpenNebula::Datastore.new_with_id(ds_id, @client) - rc = ds.info - return rc if OpenNebula.is_error?(rc) - self.update("VCENTER_DS_REF=#{ds['/DATASTORE/VCENTER_DS_REF']}", true) - end - return call(VM_METHODS[:deploy], @pe_id, host_id.to_i, From 929f01eb53a33836b56b1508838138ac994b1452 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 17 Jul 2017 17:04:57 +0200 Subject: [PATCH 15/40] F #4913: Remove templates that have images with spaces --- src/onedb/vcenter_one54_pre.rb | 60 ++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/src/onedb/vcenter_one54_pre.rb b/src/onedb/vcenter_one54_pre.rb index 3076c22a47..2788eee434 100644 --- a/src/onedb/vcenter_one54_pre.rb +++ b/src/onedb/vcenter_one54_pre.rb @@ -2156,6 +2156,7 @@ def inspect_templates(vc_templates, vc_clusters, one_clusters, tpool, ipool, vnp # Get OpenNebulas's template one_template = OpenNebula::Template.new_with_id(template["ID"], one_client) + STDOUT.puts if !template_ref @@ -2249,7 +2250,50 @@ def inspect_templates(vc_templates, vc_clusters, one_clusters, tpool, ipool, vnp dc_ref = dc._ref vcenter_name = vi_client.host STDOUT.puts "--- Discovering disks and network interfaces inside the template (please be patient)" - unmanaged = template_unmanaged_discover(vc_template["config.hardware.device"], + + devices = vc_template["config.hardware.device"] + + has_spaces = false + devices.each do |device| + if !(device.class.ancestors.index(RbVmomi::VIM::VirtualDisk)).nil? + image_path = device.backing.fileName.sub(/^\[(.*?)\] /, "") + if image_path.include?(" ") + has_spaces = true + break + end + end + end + + if has_spaces + STDOUT.puts + STDOUT.puts("\n\e[93mWARNING: Manual intervention required!\e[39m") + STDOUT.puts "Template #{one_template["ID"]}: '#{one_template["NAME"]}' is not compatible." + STDOUT.puts + STDOUT.puts "Images in this template contain spaces, which is not supported." + STDOUT.puts "You need to remove the spaces from the paths and import it again" + STDOUT.puts "in OpenNebula 5.4." + STDOUT.puts + STDOUT.puts "Press 'y' to delete the template from OpenNebula." + STDOUT.puts "Alternatively press 'q' to quit the premigrator" + STDOUT.puts "in order to fix the path before running the premigrator again." + STDOUT.puts "(y/q)" + STDOUT.puts + + loop do + option = STDIN.gets.strip + case option + when "y" + rc = one_template.delete + raise "Template #{one_template["ID"]}: '#{one_template["NAME"]}' could not be deleted. Reason #{rc.message}" if OpenNebula.is_error?(rc) + break + when "q" + exit 0 + end + end + next + end + + unmanaged = template_unmanaged_discover(devices, template_cluster, ccr_ref, vcenter_name, @@ -2425,6 +2469,9 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i STDOUT.puts "VM \e[96m#{vm_name}\e[39m could not be migrated, \e[91mcannot find this VM in objects retrieved\e[39m,\n"\ "maybe it was deleted in vCenter but not in OpenNebula?" STDOUT.puts + STDOUT.puts "Press any key to continue." + STDIN.gets + STDOUT.puts STDOUT.puts "-" * 80 STDOUT.puts next @@ -2505,7 +2552,7 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i end end - # Try to get moref using the templates uuid note that that uuid + # Try to get moref using the templates uuid. Note that that uuid # is not unique templates_same_uuid = {} if !template_ref && template_uuid @@ -2568,7 +2615,7 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i STDOUT.puts("#{template_refs.size+1}: None of the above.") loop do - STDOUT.print("\nFrom the list above, please \e[95mpick up one number\e[39m in order to specify the venter template that this VM was based on: ") + STDOUT.print("\nFrom the list above, please \e[95mpick a number\e[39m in order to specify the venter template that this VM was based on: ") template_index = STDIN.gets.strip.to_i next if template_index == 0 || template_index - 1 < 0 || template_index > template_refs.size + 1 template_ref = template_refs[template_index-1] rescue nil @@ -2581,6 +2628,13 @@ def inspect_vms(vc_vmachines, vc_templates, vc_clusters, one_clusters, vmpool, i STDOUT.puts end + if !template_ref + # This VM doesn't have an associated template any more. Let's + # treat it as a wild VM + vm_wild = true + template_ref = vm_ref + end + # Get VM's datacenter name dc = get_dc(vc_vmachine_object) dc_name = dc.name From 60f7bddb96d038b2b97ef51350b31f6422049c1e Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 17 Jul 2017 17:06:20 +0200 Subject: [PATCH 16/40] F #4913: Speed up monitorization --- src/vmm_mad/remotes/lib/vcenter_driver/host.rb | 10 ++++++++-- .../remotes/lib/vcenter_driver/vi_helper.rb | 14 +++++++------- .../remotes/lib/vcenter_driver/virtual_machine.rb | 12 +++++++++--- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/host.rb b/src/vmm_mad/remotes/lib/vcenter_driver/host.rb index cc908f075a..0e6fd1e1a0 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/host.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/host.rb @@ -430,6 +430,8 @@ class ClusterComputeResource get_resource_pool_list if !@rp_list + vm_pool = VCenterDriver::VIHelper.one_pool(OpenNebula::VirtualMachinePool) + vms.each do |vm_ref,info| begin vm = VCenterDriver::VirtualMachine.new_from_ref(vm_ref, @vi_client) @@ -466,14 +468,18 @@ class ClusterComputeResource one_vm = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualMachinePool, "DEPLOY_ID", vm_ref, - vc_uuid) + vc_uuid, + vm_pool) number = one_vm["ID"] if one_vm end if number != -1 next if @monitored_vms.include? number @monitored_vms << number - vm.one_item if vm.get_vm_id + + if vm.get_vm_id(vm_pool) + vm.one_item + end end vm.monitor(stats) diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/vi_helper.rb b/src/vmm_mad/remotes/lib/vcenter_driver/vi_helper.rb index dbd74715b1..6b2df72546 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/vi_helper.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/vi_helper.rb @@ -45,7 +45,7 @@ class VIHelper def self.find_by_name(the_class, name, pool = nil, raise_if_fail = true) pool = one_pool(the_class, raise_if_fail) if pool.nil? - element = pool.select{|e| e['NAME'] == "#{name}" }.first rescue nil + element = pool.find{|e| e['NAME'] == "#{name}" } if element.nil? && raise_if_fail raise "Could not find element '#{name}' in pool '#{the_class}'" else @@ -55,28 +55,28 @@ class VIHelper def self.find_by_ref(the_class, attribute, ref, vcenter_uuid, pool = nil) pool = one_pool(the_class, false) if pool.nil? - element = pool.select{|e| + element = pool.find{|e| e["#{attribute}"] == ref && (!e["TEMPLATE/OPENNEBULA_MANAGED"] || e["TEMPLATE/OPENNEBULA_MANAGED"] != "NO") && (e["TEMPLATE/VCENTER_INSTANCE_ID"] == vcenter_uuid || - e["USER_TEMPLATE/VCENTER_INSTANCE_ID"] == vcenter_uuid)}.first rescue nil + e["USER_TEMPLATE/VCENTER_INSTANCE_ID"] == vcenter_uuid)} return element end def self.find_image_by_path(the_class, path, ds_id, pool = nil) pool = one_pool(the_class, false) if pool.nil? - element = pool.select{|e| + element = pool.find{|e| e["PATH"] == path && - e["DATASTORE_ID"] == ds_id}.first rescue nil + e["DATASTORE_ID"] == ds_id} return element end def self.find_persistent_image_by_source(source, pool) - element = pool.select{|e| + element = pool.find{|e| e["SOURCE"] == source && e["PERSISTENT"] == "1" - }.first rescue nil + } return element end diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb index 68c370444a..afeae53fb1 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb @@ -919,7 +919,11 @@ class VirtualMachine < Template end # @return String the vm_id stored in vCenter - def get_vm_id + def get_vm_id(vm_pool = nil) + if defined?(@one_item_id) && @one_item_id + return @one_item_id + end + vm_ref = self['_ref'] return nil if !vm_ref @@ -928,10 +932,12 @@ class VirtualMachine < Template one_vm = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualMachinePool, "DEPLOY_ID", vm_ref, - vc_uuid) + vc_uuid, + vm_pool) return nil if !one_vm - return one_vm["ID"] + @one_item_id = one_vm["ID"] + return @one_item_id end def get_vcenter_instance_uuid From 6606f9fc58fbaffbe46ff365e3e6d4e3f3b7022d Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Mon, 17 Jul 2017 17:30:11 +0200 Subject: [PATCH 17/40] F #4913: Use the pool instead of querying opennebula --- src/vmm_mad/remotes/lib/vcenter_driver/host.rb | 14 +++++++------- .../remotes/lib/vcenter_driver/virtual_machine.rb | 10 +++++----- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/host.rb b/src/vmm_mad/remotes/lib/vcenter_driver/host.rb index 0e6fd1e1a0..8003caf7f0 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/host.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/host.rb @@ -464,21 +464,21 @@ class ClusterComputeResource number = matches[1] if matches # Extract vmid from ref and vcenter instance uuid if possible + one_vm = nil if number == -1 one_vm = VCenterDriver::VIHelper.find_by_ref(OpenNebula::VirtualMachinePool, "DEPLOY_ID", vm_ref, vc_uuid, vm_pool) - number = one_vm["ID"] if one_vm - end + if one_vm + number = one_vm["ID"] - if number != -1 - next if @monitored_vms.include? number - @monitored_vms << number + next if @monitored_vms.include? number + @monitored_vms << number - if vm.get_vm_id(vm_pool) - vm.one_item + vm.one_item = one_vm + vm.vm_id = number end end diff --git a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb index afeae53fb1..4db53301a6 100644 --- a/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb +++ b/src/vmm_mad/remotes/lib/vcenter_driver/virtual_machine.rb @@ -818,7 +818,7 @@ class VirtualMachine < Template VM_SHUTDOWN_TIMEOUT = 600 #10 minutes til poweroff hard - attr_accessor :item + attr_accessor :item, :vm_id attr_accessor :vm_info @@ -920,8 +920,8 @@ class VirtualMachine < Template # @return String the vm_id stored in vCenter def get_vm_id(vm_pool = nil) - if defined?(@one_item_id) && @one_item_id - return @one_item_id + if defined?(@vm_id) && @vm_id + return @vm_id end vm_ref = self['_ref'] @@ -936,8 +936,8 @@ class VirtualMachine < Template vm_pool) return nil if !one_vm - @one_item_id = one_vm["ID"] - return @one_item_id + @vm_id = one_vm["ID"] + return @vm_id end def get_vcenter_instance_uuid From 091b76ec249704d3604e2810199efba8bc222a2b Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Tue, 18 Jul 2017 10:45:35 +0200 Subject: [PATCH 18/40] fsck returns a hash of versions instead of string --- src/onedb/database_schema.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/src/onedb/database_schema.rb b/src/onedb/database_schema.rb index 5ea74e2016..7a77b8f351 100644 --- a/src/onedb/database_schema.rb +++ b/src/onedb/database_schema.rb @@ -76,6 +76,7 @@ class OneDBBacKEnd if !version if self.respond_to?(:db_version) version = db_version + version = version[:local_version] if Hash === version else version = LATEST_DB_VERSION end From f66e022ba81970c4b62689eab65bf22c262557e0 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 18 Jul 2017 13:43:30 +0200 Subject: [PATCH 19/40] Update XSD documents --- share/doc/xsd/acct.xsd | 4 +++- share/doc/xsd/host.xsd | 4 ++++ share/doc/xsd/image.xsd | 1 + share/doc/xsd/test.sh | 3 +++ share/doc/xsd/vm.xsd | 6 +++--- 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/share/doc/xsd/acct.xsd b/share/doc/xsd/acct.xsd index 16cf56fa98..d4fd284589 100644 --- a/share/doc/xsd/acct.xsd +++ b/share/doc/xsd/acct.xsd @@ -78,7 +78,9 @@ MONITOR_ACTION = 44 --> - + + + diff --git a/share/doc/xsd/host.xsd b/share/doc/xsd/host.xsd index 7bf1d449ae..79ff68a584 100644 --- a/share/doc/xsd/host.xsd +++ b/share/doc/xsd/host.xsd @@ -31,6 +31,8 @@ + + @@ -46,6 +48,8 @@ + + diff --git a/share/doc/xsd/image.xsd b/share/doc/xsd/image.xsd index abcff11517..2f574edab6 100644 --- a/share/doc/xsd/image.xsd +++ b/share/doc/xsd/image.xsd @@ -78,6 +78,7 @@ + diff --git a/share/doc/xsd/test.sh b/share/doc/xsd/test.sh index ac23f4a5f2..eb43c78655 100755 --- a/share/doc/xsd/test.sh +++ b/share/doc/xsd/test.sh @@ -41,6 +41,9 @@ onehost create host01 --im dummy --vm dummy onehost create host02 --im dummy --vm dummy onehost create host03 --im dummy --vm dummy +#Wait to monitor hosts +sleep 30 + onecluster addhost newcluster host03 for i in `onehost list | tail -n +2 | tr -s ' ' | cut -f2 -d ' '`; do diff --git a/share/doc/xsd/vm.xsd b/share/doc/xsd/vm.xsd index 93b6c0df03..69ae7abfc7 100644 --- a/share/doc/xsd/vm.xsd +++ b/share/doc/xsd/vm.xsd @@ -72,9 +72,6 @@ - - - @@ -138,6 +135,9 @@ MONITOR_ACTION = 44 --> + + + From a9fdee48103c8e23486852c71ba86d86fa95a4eb Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 18 Jul 2017 13:44:58 +0200 Subject: [PATCH 20/40] B : Load vm_info from history records --- src/vm/History.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/vm/History.cc b/src/vm/History.cc index a987eceb29..eb7eeb0d25 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -343,6 +343,8 @@ string& History::to_xml(string& xml, bool database) const int History::rebuild_attributes() { + vector content; + int int_action; int rc = 0; @@ -375,6 +377,26 @@ int History::rebuild_attributes() action = static_cast(int_action); + // ------------------------------------------------------------------------- + ObjectXML::get_nodes("/HISTORY/VM", content); + + if (content.empty()) + { + return -1; + } + + ObjectXML vm_info_xml(content[0]); + + ostringstream oss; + + oss << vm_info_xml; + + vm_info = oss.str(); + + ObjectXML::free_nodes(content); + + content.clear(); + non_persistent_data(); if (rc != 0) From 57e65f50dbb81892d7eeb5afd1ba28f5c6cdf927 Mon Sep 17 00:00:00 2001 From: abelCoronado93 Date: Tue, 18 Jul 2017 14:10:39 +0200 Subject: [PATCH 21/40] Solved bug when updating volatile disk --- .../form-panels/create/wizard-tabs/storage/disk-tab.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js index 1ef42fe6f0..16379a7c4c 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/storage/disk-tab.js @@ -148,7 +148,11 @@ define(function(require) { var tmpl = WizardFields.retrieve(selectedContext); - if(!tmpl["IMAGE"] && !tmpl["IMAGE_ID"]){ + if(tmpl.SIZE){ + tmpl.SIZE = tmpl.SIZE * 1024; + } + + if($("input[name='" + this.diskTabId + "']:checked", context).val() == "image" && !tmpl["IMAGE"] && !tmpl["IMAGE_ID"]){ return {}; } var dev_prefix = WizardFields.retrieveInput($('#disk_dev_prefix', selectedContext)); From 5f28a7bf9b0ca7d48621d24614931da833790c2e Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Tue, 18 Jul 2017 18:19:30 +0200 Subject: [PATCH 22/40] B: Solves issues when loading VM template in history records --- include/ObjectXML.h | 16 +++++++++++----- src/vm/History.cc | 26 ++++++++++++-------------- src/vm/VirtualMachine.cc | 21 ++++++++++++--------- 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/include/ObjectXML.h b/include/ObjectXML.h index 8232bd644e..55ce85d61c 100644 --- a/include/ObjectXML.h +++ b/include/ObjectXML.h @@ -316,15 +316,21 @@ public: */ friend std::ostream& operator<<(std::ostream& os, ObjectXML& oxml) { - xmlChar * mem; - int size; + xmlNodePtr root_node = xmlDocGetRootElement(oxml.xml); - xmlDocDumpMemory(oxml.xml,&mem,&size); + if ( root_node == 0 ) + { + return os; + } - std::string str(reinterpret_cast(mem)); + xmlBufferPtr buffer = xmlBufferCreate(); + + xmlNodeDump(buffer, oxml.xml, root_node, 0, 0); + + std::string str(reinterpret_cast(buffer->content)); os << str; - xmlFree(mem); + xmlBufferFree(buffer); return os; }; diff --git a/src/vm/History.cc b/src/vm/History.cc index eb7eeb0d25..3cb8fd391f 100644 --- a/src/vm/History.cc +++ b/src/vm/History.cc @@ -380,23 +380,21 @@ int History::rebuild_attributes() // ------------------------------------------------------------------------- ObjectXML::get_nodes("/HISTORY/VM", content); - if (content.empty()) + if (!content.empty()) { - return -1; + ObjectXML vm_info_xml(content[0]); + + ostringstream oss; + + oss << vm_info_xml; + + vm_info = oss.str(); + + ObjectXML::free_nodes(content); + + content.clear(); } - ObjectXML vm_info_xml(content[0]); - - ostringstream oss; - - oss << vm_info_xml; - - vm_info = oss.str(); - - ObjectXML::free_nodes(content); - - content.clear(); - non_persistent_data(); if (rc != 0) diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index 0996ba1d9d..44ed421a48 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -505,10 +505,12 @@ int VirtualMachine::select(SqlDB * db) return rc; } - //Get History Records. Current history is built in from_xml() (if any). + //Get History Records. if( hasHistory() ) { - last_seq = history->seq - 1; + last_seq = history->seq; + + delete history_records[last_seq]; for (int i = last_seq; i >= 0; i--) { @@ -525,6 +527,10 @@ int VirtualMachine::select(SqlDB * db) history_records[i] = hp; if ( i == last_seq ) + { + history = hp; + } + else if ( i == last_seq - 1 ) { previous_history = hp; } @@ -2117,18 +2123,15 @@ int VirtualMachine::from_xml(const string &xml_str) // ------------------------------------------------------------------------- // Last history entry // ------------------------------------------------------------------------- - ObjectXML::get_nodes("/VM/HISTORY_RECORDS/HISTORY", content); + int last_seq; - if (!content.empty()) + if ( xpath(last_seq,"/VM/HISTORY_RECORDS/HISTORY/SEQ", -1) == 0 && + last_seq != -1 ) { - history = new History(oid); - rc += history->from_xml_node(content[0]); + history = new History(oid, last_seq); history_records.resize(history->seq + 1); history_records[history->seq] = history; - - ObjectXML::free_nodes(content); - content.clear(); } // ------------------------------------------------------------------------- From 333c7cd79654d43e63d578b4412fa1265e380268 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Wed, 19 Jul 2017 10:59:58 +0200 Subject: [PATCH 23/40] Solved bug custom host information (#405) --- src/sunstone/public/app/tabs/hosts-tab/form-panels/create.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/public/app/tabs/hosts-tab/form-panels/create.js b/src/sunstone/public/app/tabs/hosts-tab/form-panels/create.js index 003d8a7d48..afe05c9879 100644 --- a/src/sunstone/public/app/tabs/hosts-tab/form-panels/create.js +++ b/src/sunstone/public/app/tabs/hosts-tab/form-panels/create.js @@ -78,7 +78,7 @@ define(function(require) { $.each(Config.onedConf.IM_MAD, function(index, imMad) { if (imMad.SUNSTONE_NAME !== undefined) { that.imMadNameList.push({ - 'displayNme': imMad["SUNSTONE_NAME"], + 'displayName': imMad["SUNSTONE_NAME"], 'driverName': imMad["NAME"] }); } From fd170f21792e62fdbbbdf374478b805028186c75 Mon Sep 17 00:00:00 2001 From: Tino Vazquez Date: Wed, 19 Jul 2017 10:58:17 +0200 Subject: [PATCH 24/40] Fix for onefsck --- src/onedb/database_schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onedb/database_schema.rb b/src/onedb/database_schema.rb index 7a77b8f351..087f8cec16 100644 --- a/src/onedb/database_schema.rb +++ b/src/onedb/database_schema.rb @@ -86,7 +86,7 @@ class OneDBBacKEnd # Discard versions greater than the one we are searching for versions = VERSION_SCHEMA.keys.reject do |v| - Gem::Version.new(v) > gver + Gem::Version.new(v.dup) > gver end # Order versions in decreasing order From 8f1870ad1dd226e4ce36416441a863949dc1360e Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Wed, 19 Jul 2017 12:15:33 +0200 Subject: [PATCH 25/40] F #4894 Added terminate action with FAILURE state VMs in Sunstone (#406) --- .../app/tabs/vms-tab/utils/state-actions.js | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/sunstone/public/app/tabs/vms-tab/utils/state-actions.js b/src/sunstone/public/app/tabs/vms-tab/utils/state-actions.js index a82045f623..657b057d6d 100644 --- a/src/sunstone/public/app/tabs/vms-tab/utils/state-actions.js +++ b/src/sunstone/public/app/tabs/vms-tab/utils/state-actions.js @@ -71,7 +71,7 @@ define(function(require) { LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.SHUTDOWN ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.CANCEL ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.FAILURE ] = []; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.FAILURE ] = ["VM.terminate"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.CLEANUP_RESUBMIT ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.UNKNOWN ] = ["VM.resched", "VM.unresched", "VM.poweroff", "VM.poweroff_hard", "VM.undeploy", "VM.undeploy_hard", "VM.migrate", "VM.migrate_live", "VM.resume", "VM.terminate", "VM.terminate_hard"]; @@ -94,21 +94,21 @@ define(function(require) { LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.HOTPLUG_PROLOG_POWEROFF ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.HOTPLUG_EPILOG_POWEROFF ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_MIGRATE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_FAILURE ] = ["VM.updateconf"]; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_MIGRATE_FAILURE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_FAILURE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_FAILURE ] = ["VM.updateconf"]; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG_FAILURE ] = ["VM.updateconf"]; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG_STOP_FAILURE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG_UNDEPLOY_FAILURE ] = ["VM.updateconf"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_FAILURE ] = ["VM.updateconf", "VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_MIGRATE_FAILURE ] = ["VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_FAILURE ] = ["VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_FAILURE ] = ["VM.updateconf", "VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG_FAILURE ] = ["VM.updateconf", "VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG_STOP_FAILURE ] = ["VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.EPILOG_UNDEPLOY_FAILURE ] = ["VM.updateconf", "VM.terminate"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_POWEROFF ] = ["VM.updateconf"]; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_POWEROFF_FAILURE ] = ["VM.updateconf"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_POWEROFF_FAILURE ] = ["VM.updateconf", "VM.terminate"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_SUSPEND ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_SUSPEND_FAILURE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_UNDEPLOY_FAILURE ] = ["VM.updateconf"]; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_STOPPED_FAILURE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_RESUME_FAILURE ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_UNDEPLOY_FAILURE ] = ["VM.updateconf"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_SUSPEND_FAILURE ] = ["VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_UNDEPLOY_FAILURE ] = ["VM.updateconf", "VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.BOOT_STOPPED_FAILURE ] = ["VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_RESUME_FAILURE ] = ["VM.terminate"]; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_UNDEPLOY_FAILURE ] = ["VM.updateconf", "VM.terminate"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_POWEROFF ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_REVERT_POWEROFF ] = ["VM.updateconf"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_DELETE_POWEROFF ] = ["VM.updateconf"]; @@ -119,7 +119,7 @@ define(function(require) { LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_REVERT ] = []; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_SNAPSHOT_DELETE ] = []; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_UNKNOWN ] = []; - LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_UNKNOWN_FAILURE ] = []; + LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.PROLOG_MIGRATE_UNKNOWN_FAILURE ] = ["VM.terminate"]; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_RESIZE ] = []; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_RESIZE_POWEROFF ] = []; LCM_STATE_ACTIONS[ OpenNebulaVM.LCM_STATES.DISK_RESIZE_UNDEPLOYED ] = []; From 0c715f3aa616650478f3cc85e263d1936445c72a Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Wed, 19 Jul 2017 14:35:32 +0200 Subject: [PATCH 26/40] B: Add DS_ID and TM_MAD to last history record --- src/onedb/vcenter_one54.rb | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/onedb/vcenter_one54.rb b/src/onedb/vcenter_one54.rb index da1d58e872..4cb11cd44e 100644 --- a/src/onedb/vcenter_one54.rb +++ b/src/onedb/vcenter_one54.rb @@ -54,6 +54,41 @@ EOT Dir["#{TMP_DIR}/one_migrate_vm_*"].each do |vm_filename| vm_id = vm_filename.split("_")[-1] vm_xml = File.read(vm_filename) + + vm_xml_doc = REXML::Document.new(vm_xml).root + + seq_node = vm_xml_doc.elements["HISTORY_RECORDS/HISTORY/SEQ"] + dsid_node = vm_xml_doc.elements["HISTORY_RECORDS/HISTORY/DS_ID"] + + if seq_node && seq_node.has_text? && dsid_node && dsid_node.has_text? + seq = seq_node.text + dsid= dsid_node.text + begin + + h_dataset = @db["SELECT body from history where vid=#{vm_id} and seq=#{seq}"] + h_body = h_dataset.map(:body) + + h_xml = REXML::Document.new(h_body[0]).root + + h_ds_node = h_xml.elements["DS_ID"] + + if h_ds_node && h_ds_node.has_text? + h_ds_node.text = dsid + + h_xml.delete_element "TM_MAD" + + tmmad_elem = REXML::Element.new("TM_MAD") + tmmad_elem.text = "vcenter" + h_xml.add_element(tmmad_elem) + + @db.run("UPDATE history SET body='#{h_xml.to_s}' WHERE vid=#{vm_id} and seq=#{seq}") + end + + rescue + puts "VM #{vm_id} cannot set datastore. Manual update needed" + end + end + @db.run("UPDATE vm_pool SET body='#{vm_xml}' WHERE oid='#{vm_id}'") puts " VM #{vm_id} migrated!" if verbose end From 30d8b368026b34e648c76fb728fbe3ed18fdabfd Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Wed, 19 Jul 2017 16:52:13 +0200 Subject: [PATCH 27/40] Fix bug with imported VMs in premigrator --- src/onedb/vcenter_one54_pre.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/onedb/vcenter_one54_pre.rb b/src/onedb/vcenter_one54_pre.rb index 2788eee434..40ef201119 100644 --- a/src/onedb/vcenter_one54_pre.rb +++ b/src/onedb/vcenter_one54_pre.rb @@ -690,7 +690,7 @@ def vm_unmanaged_discover(devices, xml_doc, template_xml, if !vc_vmachines.key? vm_ref raise "Could not find vcenter vm using ref #{vm_ref} in order to assign a datastore" else - vc_system_ds = vc_vmachine["datastore"].first rescue nil + vc_system_ds = vc_vmachines[vm_ref]["datastore"].first rescue nil raise "Could not find Datastore associated with the VM" if vc_system_ds.nil? ds_ref = vc_system_ds._ref From 5757bd4a61b8e9fd6f7f2f4eb64c0f8dab20292f Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Thu, 20 Jul 2017 10:45:06 +0200 Subject: [PATCH 28/40] Fix problem with rubygems from ruby 1.9 --- src/onedb/database_schema.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/onedb/database_schema.rb b/src/onedb/database_schema.rb index 087f8cec16..a1e9b6f7f1 100644 --- a/src/onedb/database_schema.rb +++ b/src/onedb/database_schema.rb @@ -82,7 +82,7 @@ class OneDBBacKEnd end end - gver = Gem::Version.new(version) + gver = Gem::Version.new(version.dup) # Discard versions greater than the one we are searching for versions = VERSION_SCHEMA.keys.reject do |v| @@ -91,7 +91,7 @@ class OneDBBacKEnd # Order versions in decreasing order versions.sort! do |a, b| - Gem::Version.new(b) <=> Gem::Version.new(a) + Gem::Version.new(b.dup) <=> Gem::Version.new(a.dup) end schema = nil From 5c4b9f9e312c4390dd329e584c4e73ad709add01 Mon Sep 17 00:00:00 2001 From: Javi Fontan Date: Thu, 20 Jul 2017 11:03:50 +0200 Subject: [PATCH 29/40] Change ec2 type names in onehost create help --- src/cli/one_helper/onehost_helper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cli/one_helper/onehost_helper.rb b/src/cli/one_helper/onehost_helper.rb index e2a79c016d..4efc658899 100644 --- a/src/cli/one_helper/onehost_helper.rb +++ b/src/cli/one_helper/onehost_helper.rb @@ -32,9 +32,9 @@ class OneHostHelper < OpenNebulaHelper::OneHelper # EC2_SECRET = # # CAPACITY = [ - # M1SMALL = , - # M1XLARGE = , - # M1LARGE = + # M1_SMALL = , + # M1_XLARGE = , + # M1_LARGE = # ] # # You can set any machine type supported by ec2 From 2911648e079e2b162a059aa2abc0359a9a2f3d63 Mon Sep 17 00:00:00 2001 From: semedi Date: Thu, 20 Jul 2017 10:53:34 +0200 Subject: [PATCH 30/40] ec2 capacities FIX --- src/onedb/local/4.90.0_to_5.3.80.rb | 2 +- src/vmm_mad/remotes/ec2/ec2_driver.rb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/onedb/local/4.90.0_to_5.3.80.rb b/src/onedb/local/4.90.0_to_5.3.80.rb index 84b34843d8..f7e2af2b0f 100644 --- a/src/onedb/local/4.90.0_to_5.3.80.rb +++ b/src/onedb/local/4.90.0_to_5.3.80.rb @@ -126,7 +126,7 @@ module Migrator capacity = doc.create_element("CAPACITY") host_info["capacity"].each { |k, v| - name = k[0..1] << k[3..k.length-1] + name = k.gsub(".", "_") capacity.add_child(doc.create_element(name.upcase, v)) } diff --git a/src/vmm_mad/remotes/ec2/ec2_driver.rb b/src/vmm_mad/remotes/ec2/ec2_driver.rb index 49139a4eff..e2062a3369 100755 --- a/src/vmm_mad/remotes/ec2/ec2_driver.rb +++ b/src/vmm_mad/remotes/ec2/ec2_driver.rb @@ -454,8 +454,7 @@ class EC2Driver # Parse template instance type into # Amazon ec2 format (M1SMALL => m1.small) def parse_inst_type(type) - fixed_type = type[0..1]<< '.' << type[2..type.length+1] - return fixed_type.downcase + return type.downcase.gsub("_", ".") end # Get the info of all the EC2 instances. An EC2 instance must include From d4367953711e05f7aef1bbc4ca98a34a589d2011 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Fri, 21 Jul 2017 13:06:41 +0200 Subject: [PATCH 31/40] F #5217 Added ds requirements instantiate VM (#407) * Added ds requirements instantiate VM * Solved bug in VMGroup datatable cloud view * F #5217 Added DS Requirements cloud view instantiate VM * F #5217 Added SYSTEM filter in DS datatable * F #5217 Made configurable ds and host datatables instantiate VM --- src/sunstone/etc/sunstone-views/admin.yaml | 6 ++ .../etc/sunstone-views/admin_vcenter.yaml | 6 ++ src/sunstone/etc/sunstone-views/cloud.yaml | 20 +++++- .../etc/sunstone-views/groupadmin.yaml | 6 ++ src/sunstone/etc/sunstone-views/user.yaml | 6 ++ src/sunstone/public/app/tabs/provision-tab.js | 57 ++++++++++++++- .../app/tabs/provision-tab/vms/create.hbs | 10 +++ .../create/wizard-tabs/scheduling.js | 1 + .../templates-tab/form-panels/instantiate.js | 71 ++++++++++++++++--- .../form-panels/instantiate/templateRow.hbs | 25 ++++++- 10 files changed, 195 insertions(+), 13 deletions(-) diff --git a/src/sunstone/etc/sunstone-views/admin.yaml b/src/sunstone/etc/sunstone-views/admin.yaml index 59f9963e79..9965e930e7 100644 --- a/src/sunstone/etc/sunstone-views/admin.yaml +++ b/src/sunstone/etc/sunstone-views/admin.yaml @@ -56,6 +56,12 @@ features: # True to show the option to make an instance persistent instantiate_persistent: true + # True to show the datastore datatable to instantiate VM + show_ds_instantiate: true + + # True to show the host datatable to instantiate VM + show_host_instantiate: true + # True to show an input to specify the the VMs and Template path/folder where a vCenter VM will # deployed to vcenter_vm_folder: false diff --git a/src/sunstone/etc/sunstone-views/admin_vcenter.yaml b/src/sunstone/etc/sunstone-views/admin_vcenter.yaml index 5583046484..3c9b6ed7dc 100644 --- a/src/sunstone/etc/sunstone-views/admin_vcenter.yaml +++ b/src/sunstone/etc/sunstone-views/admin_vcenter.yaml @@ -56,6 +56,12 @@ features: # True to show the option to make an instance persistent instantiate_persistent: true + # True to show the datastore datatable to instantiate VM + show_ds_instantiate: false + + # True to show the host datatable to instantiate VM + show_host_instantiate: false + # True to show an input to specify the the VMs and Template path/folder where a vCenter VM will # deployed to vcenter_vm_folder: true diff --git a/src/sunstone/etc/sunstone-views/cloud.yaml b/src/sunstone/etc/sunstone-views/cloud.yaml index e0399756d4..428b71a36c 100644 --- a/src/sunstone/etc/sunstone-views/cloud.yaml +++ b/src/sunstone/etc/sunstone-views/cloud.yaml @@ -88,6 +88,8 @@ tabs: vmgroup_select: true # True to allow DISK size customization disk_resize: true + # True to allow datastore customization + datastore_select: true settings-tab: panel_tabs: settings_info_tab: false @@ -153,4 +155,20 @@ tabs: - 4 # Owner - 5 # Vms #- 6 # Labels - #- 7 # Search data \ No newline at end of file + #- 7 # Search data + datastores-tab: + table_columns: + - 0 # Checkbox + - 1 # ID + - 2 # Owner + - 3 # Group + - 4 # Name + #- 5 # Capacity + #- 6 # Cluster + #- 7 # Basepath + #- 8 # TM + #- 9 # DS + #- 10 # Type + - 11 # Status + #- 12 # Labels + #- 13 # Search data \ No newline at end of file diff --git a/src/sunstone/etc/sunstone-views/groupadmin.yaml b/src/sunstone/etc/sunstone-views/groupadmin.yaml index 230a0ccee8..1795a6e60d 100644 --- a/src/sunstone/etc/sunstone-views/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/groupadmin.yaml @@ -56,6 +56,12 @@ features: # True to show the option to make an instance persistent instantiate_persistent: true + # True to show the datastore datatable to instantiate VM + show_ds_instantiate: false + + # True to show the host datatable to instantiate VM + show_host_instantiate: false + # True to show an input to specify the the VMs and Template path/folder where a vCenter VM will # deployed to vcenter_vm_folder: false diff --git a/src/sunstone/etc/sunstone-views/user.yaml b/src/sunstone/etc/sunstone-views/user.yaml index 219138323b..d7c8af53a0 100644 --- a/src/sunstone/etc/sunstone-views/user.yaml +++ b/src/sunstone/etc/sunstone-views/user.yaml @@ -56,6 +56,12 @@ features: # True to show the option to make an instance persistent instantiate_persistent: true + # True to show the datastore datatable to instantiate VM + show_ds_instantiate: false + + # True to show the host datatable to instantiate VM + show_host_instantiate: false + # True to show an input to specify the the VMs and Template path/folder where a vCenter VM will # deployed to vcenter_vm_folder: false diff --git a/src/sunstone/public/app/tabs/provision-tab.js b/src/sunstone/public/app/tabs/provision-tab.js index 30638bdd61..c418d787e8 100644 --- a/src/sunstone/public/app/tabs/provision-tab.js +++ b/src/sunstone/public/app/tabs/provision-tab.js @@ -40,6 +40,8 @@ define(function(require) { var UserInputs = require('utils/user-inputs'); var CapacityInputs = require('tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs'); var LabelsUtils = require('utils/labels/utils'); + var DatastoresTable = require('tabs/datastores-tab/datatable'); + var UniqueId = require('utils/unique-id'); var ProvisionVmsList = require('./provision-tab/vms/list'); var ProvisionTemplatesList = require('./provision-tab/templates/list'); @@ -92,6 +94,7 @@ define(function(require) { $("#vm_name", context).val(''); $(".provision_selected_networks").html(""); $(".provision_vmgroup_selector").html(""); + $(".provision_ds_selector").html(""); $(".provision-pricing-table", context).removeClass("selected"); $(".alert-box-error", context).hide(); $(".total_cost_div", context).hide(); @@ -569,8 +572,10 @@ define(function(require) { $("#provision_create_vm .provision_disk_selector").removeData("template_json"); $("#provision_create_vm .provision_network_selector").html(""); $("#provision_create_vm .provision_vmgroup_selector").html(""); + $("#provision_create_vm .provision_ds_selector").html(""); $("#provision_create_vm .provision_add_vmgroup").show(); $("#provision_create_vm .provision_vmgroup").hide(); + $("#provision_create_vm .provision_ds").hide(); $("#provision_create_vm .provision_custom_attributes_selector").html("") @@ -595,12 +600,13 @@ define(function(require) { $(".provision_vmgroup_selector", context).html(""); $(".provision_add_vmgroup", context).show(); $(".provision_vmgroup", context).hide(); + //$(".provision_ds", context).hide(); $(".provision_custom_attributes_selector", context).html(""); $(".provision_accordion_flow_template .selected_template", context).hide(); $(".provision_accordion_flow_template .select_template", context).show(); - $("li:not(.is-active) a[href='#provision_dd_flow_template']", context).trigger("click") + $("li:not(.is-active) a[href='#provision_dd_flow_template']", context).trigger("click"); $(".total_cost_div", context).hide(); $(".alert-box-error", context).hide(); @@ -946,6 +952,7 @@ define(function(require) { $(".provision_accordion_template a").first().trigger("click"); $("#provision_create_vm .provision_vmgroup").show(); + $("#provision_create_vm .provision_ds").show(); OpenNebula.Template.show({ data : { id: template_id, @@ -983,11 +990,45 @@ define(function(require) { } if (Config.provision.create_vm.isEnabled("vmgroup_select")) { + $(".provision_vmgroup_selector", create_vm_context).html(""); + $("#provision_create_vm .provision_add_vmgroup").show(); VMGroupSection.insert(template_json, $(".vmgroupContext", create_vm_context)); } else { $(".provision_vmgroup_selector", create_vm_context).html(""); } + if (Config.provision.create_vm.isEnabled("datastore_select")) { + $(".provision_ds_selector", create_vm_context).html(""); + var options = { + 'select': true, + 'selectOptions': { + 'multiple_choice': true + } + } + this.datastoresTable = new DatastoresTable('DatastoresTable' + UniqueId.id(), options); + $(".provision_ds_selector", create_vm_context).html(this.datastoresTable.dataTableHTML); + this.datastoresTable.initialize(); + this.datastoresTable.filter("system", 10); + this.datastoresTable.refreshResourceTableSelect(); + if(template_json.VMTEMPLATE.TEMPLATE.SCHED_DS_REQUIREMENTS){ + var dsReqJSON = template_json.VMTEMPLATE.TEMPLATE.SCHED_DS_REQUIREMENTS; + var dsReq = TemplateUtils.escapeDoubleQuotes(dsReqJSON); + var ds_id_regexp = /(\s|\||\b)ID=\\"([0-9]+)\\"/g; + var ds = []; + while (match = ds_id_regexp.exec(dsReq)) { + ds.push(match[2]); + } + var selectedResources = { + ids : ds + } + this.datastoresTable.selectResourceTableSelect(selectedResources); + $(".provision_ds_selector", create_vm_context).data("dsTable", this.datastoresTable); + } + } else { + $(".provision_ds_selector", create_vm_context).html(""); + $(".provision_ds", create_vm_context).hide(); + } + if (template_json.VMTEMPLATE.TEMPLATE.USER_INPUTS) { UserInputs.vmTemplateInsert( $(".provision_custom_attributes_selector", create_vm_context), @@ -1044,6 +1085,20 @@ define(function(require) { $.extend(extra_info.template, vmgroup); } + var dsTable = $(".provision_ds_selector", context).data("dsTable"); + if(dsTable != undefined){ + var req_string = []; + var ds = dsTable.retrieveResourceTableSelect(); + if(ds){ + $.each(ds, function(index, dsId) { + req_string.push('ID="' + dsId + '"'); + }); + req_string = req_string.join(" | "); + req_string = TemplateUtils.escapeDoubleQuotes(req_string); + extra_info.template.SCHED_DS_REQUIREMENTS = req_string; + } + } + if (nics.length > 0) { extra_info.template.nic = nics; } diff --git a/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs b/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs index 7f2fd3ac8f..56544be5fe 100644 --- a/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs +++ b/src/sunstone/public/app/tabs/provision-tab/vms/create.hbs @@ -140,4 +140,14 @@
+ \ No newline at end of file diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js index 88dbbfbe66..97f35bf12a 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/scheduling.js @@ -129,6 +129,7 @@ define(function(require) { that.clustersTable.initialize(selectOptions); that.clustersTable.refreshResourceTableSelect(); that.datastoresTable.initialize(selectOptions); + that.datastoresTable.filter("system", 10); that.datastoresTable.refreshResourceTableSelect(); } diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js index 3dcb1d75aa..a07a6126ce 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate.js @@ -29,6 +29,7 @@ define(function(require) { var Tips = require('utils/tips'); var UserInputs = require('utils/user-inputs'); var WizardFields = require('utils/wizard-fields'); + var TemplateUtils = require('utils/template-utils'); var DisksResize = require('utils/disks-resize'); var NicsSection = require('utils/nics-section'); var VMGroupSection = require('utils/vmgroup-section'); @@ -36,6 +37,7 @@ define(function(require) { var CapacityInputs = require('tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-inputs'); var Config = require('sunstone-config'); var HostsTable = require('tabs/hosts-tab/datatable'); + var DatastoresTable = require('tabs/datastores-tab/datatable'); /* CONSTANTS @@ -182,6 +184,11 @@ define(function(require) { tmp_json.SCHED_REQUIREMENTS = sched; } + var sched_ds = WizardFields.retrieveInput($("#SCHED_DS_REQUIREMENTS" + template_id, context)); + if(sched_ds){ + tmp_json.SCHED_DS_REQUIREMENTS = sched_ds; + } + var nics = []; var pcis = []; @@ -266,6 +273,7 @@ define(function(require) { timeout: true, success: function (request, template_json) { that.template_objects.push(template_json); + var options = { 'select': true, 'selectOptions': { @@ -274,26 +282,68 @@ define(function(require) { } that.hostsTable = new HostsTable('HostsTable' + template_json.VMTEMPLATE.ID, options); + that.datastoresTable = new DatastoresTable('DatastoresTable' + template_json.VMTEMPLATE.ID, options); + templatesContext.append( TemplateRowHTML( { element: template_json.VMTEMPLATE, capacityInputsHTML: CapacityInputs.html(), - hostsDatatable: that.hostsTable.dataTableHTML + hostsDatatable: that.hostsTable.dataTableHTML, + dsDatatable: that.datastoresTable.dataTableHTML }) ); $(".provision_host_selector" + template_json.VMTEMPLATE.ID, context).data("hostsTable", that.hostsTable); + $(".provision_ds_selector" + template_json.VMTEMPLATE.ID, context).data("dsTable", that.datastoresTable); + var selectOptions = { 'selectOptions': { 'select_callback': function(aData, options) { - generateRequirements($(".provision_host_selector" + template_json.VMTEMPLATE.ID, context).data("hostsTable"), context, template_json.VMTEMPLATE.ID); + var hostTable = $(".provision_host_selector" + template_json.VMTEMPLATE.ID, context).data("hostsTable"); + var dsTable = $(".provision_ds_selector" + template_json.VMTEMPLATE.ID, context).data("dsTable"); + generateRequirements(hostTable, dsTable, context, template_json.VMTEMPLATE.ID); }, 'unselect_callback': function(aData, options) { - generateRequirements($(".provision_host_selector"+ template_json.VMTEMPLATE.ID, context).data("hostsTable"), context, template_json.VMTEMPLATE.ID); - } + var hostTable = $(".provision_host_selector" + template_json.VMTEMPLATE.ID, context).data("hostsTable"); + var dsTable = $(".provision_ds_selector" + template_json.VMTEMPLATE.ID, context).data("dsTable"); + generateRequirements(hostTable, dsTable, context, template_json.VMTEMPLATE.ID); + } } } that.hostsTable.initialize(selectOptions); that.hostsTable.refreshResourceTableSelect(); + that.datastoresTable.initialize(selectOptions); + that.datastoresTable.filter("system", 10); + that.datastoresTable.refreshResourceTableSelect(); + + var reqJSON = template_json.VMTEMPLATE.TEMPLATE.SCHED_REQUIREMENTS; + if (reqJSON) { + $('#SCHED_REQUIREMENTS' + template_json.VMTEMPLATE.ID, context).val(reqJSON); + var req = TemplateUtils.escapeDoubleQuotes(reqJSON); + var host_id_regexp = /(\s|\||\b)ID=\\"([0-9]+)\\"/g; + var hosts = []; + while (match = host_id_regexp.exec(req)) { + hosts.push(match[2]); + } + var selectedResources = { + ids : hosts + } + that.hostsTable.selectResourceTableSelect(selectedResources); + } + + var dsReqJSON = template_json.VMTEMPLATE.TEMPLATE.SCHED_DS_REQUIREMENTS; + if (dsReqJSON) { + $('#SCHED_DS_REQUIREMENTS' + template_json.VMTEMPLATE.ID, context).val(dsReqJSON); + var dsReq = TemplateUtils.escapeDoubleQuotes(dsReqJSON); + var ds_id_regexp = /(\s|\||\b)ID=\\"([0-9]+)\\"/g; + var ds = []; + while (match = ds_id_regexp.exec(dsReq)) { + ds.push(match[2]); + } + var selectedResources = { + ids : ds + } + that.datastoresTable.selectResourceTableSelect(selectedResources); + } DisksResize.insert({ template_json: template_json, @@ -383,21 +433,22 @@ define(function(require) { Tips.setup(context); return false; } - function generateRequirements(hosts_table, context, id) { + + function generateRequirements(hosts_table, ds_table, context, id) { var req_string=[]; - //var req_ds_string=[]; + var req_ds_string=[]; var selected_hosts = hosts_table.retrieveResourceTableSelect(); - //var selected_ds = this.datastoresTable.retrieveResourceTableSelect(); + var selected_ds = ds_table.retrieveResourceTableSelect(); $.each(selected_hosts, function(index, hostId) { req_string.push('ID="'+hostId+'"'); }); - /*$.each(selected_ds, function(index, dsId) { + $.each(selected_ds, function(index, dsId) { req_ds_string.push('ID="'+dsId+'"'); - });*/ + }); $('#SCHED_REQUIREMENTS' + id, context).val(req_string.join(" | ")); - //$('#SCHED_DS_REQUIREMENTS', context).val(req_ds_string.join(" | ")); + $('#SCHED_DS_REQUIREMENTS' + id, context).val(req_ds_string.join(" | ")); }; }); diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs index 9ea6dd7639..a41df9e6cf 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/instantiate/templateRow.hbs @@ -67,6 +67,7 @@ + {{#isFeatureEnabled "show_host_instantiate"}}
@@ -86,7 +87,29 @@
-
+ {{/isFeatureEnabled}} + {{#isFeatureEnabled "show_ds_instantiate"}} +
+
+
+ + {{tr "Datastore"}} + +
{{{dsDatatable}}}
+
+
+ + +
+
+
+
+
+ {{/isFeatureEnabled}} +
From ea84b0b446ada318d1c0dd17d5933191b4c34b71 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Mon, 24 Jul 2017 15:44:15 +0200 Subject: [PATCH 32/40] Solved NaN Cost in general panel VM Template (#409) --- .../create/wizard-tabs/general/capacity-create.js | 13 +++++++++++-- .../form-panels/create/wizard-tabs/general/html.hbs | 2 +- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-create.js b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-create.js index 9cb6d7cb26..572c00dc70 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-create.js +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/capacity-create.js @@ -84,8 +84,17 @@ define(function(require) { } function _totalCost(){ - var total = document.getElementById('real_memory_cost').value + document.getElementById('real_cpu_cost').value; - document.getElementById('total_cost').textContent = "Total: "+ convertCostNumber(total); + var memory = document.getElementById('real_memory_cost').value; + var cpu = document.getElementById('real_cpu_cost').value; + if(memory === undefined && cpu === undefined){ + document.getElementById('total_cost').textContent = "Total: 0.00"; + } else if(memory === undefined){ + document.getElementById('total_cost').textContent = "Total: " + convertCostNumber(cpu); + } else if(cpu === undefined){ + document.getElementById('total_cost').textContent = "Total: " + convertCostNumber(memory); + } else { + document.getElementById('total_cost').textContent = "Total: " + convertCostNumber(memory + cpu); + } } function _calculatedRealMemory(){ diff --git a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs index 48098a1d73..4781ed4e99 100644 --- a/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs +++ b/src/sunstone/public/app/tabs/templates-tab/form-panels/create/wizard-tabs/general/html.hbs @@ -119,7 +119,7 @@ {{tr "Cost"}} - 0.00 + {{tr "COST"}} / {{tr "MONTH"}} From a0cc06320faf10643de47b155bfa02c7cda5e886 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Mon, 24 Jul 2017 15:44:33 +0200 Subject: [PATCH 33/40] B #4978 Solved bug in date sorting 'Registration Time' (#410) --- src/sunstone/public/app/app.js | 27 +++++++++++++++++++ .../app/tabs/marketplaceapps-tab/datatable.js | 5 ++-- .../tabs/templates-tab/datatable-common.js | 5 ++-- src/sunstone/public/app/utils/humanize.js | 17 +++++++++++- 4 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/sunstone/public/app/app.js b/src/sunstone/public/app/app.js index 5d14d3416e..fa7375a729 100644 --- a/src/sunstone/public/app/app.js +++ b/src/sunstone/public/app/app.js @@ -294,6 +294,33 @@ define(function(require) { } } + jQuery.extend( jQuery.fn.dataTableExt.oSort, { + "date-euro-pre": function ( a ) { + var x; + + if ( $.trim(a) !== '' ) { + var frDatea = $.trim(a).split(' '); + var frTimea = (undefined != frDatea[1]) ? frDatea[1].split(':') : [00,00,00]; + var frDatea2 = frDatea[0].split('/'); + x = (frDatea2[2] + frDatea2[1] + frDatea2[0] + frTimea[0] + frTimea[1] + ((undefined != frTimea[2]) ? frTimea[2] : 0)) * 1; + } + else { + x = Infinity; + } + + return x; + }, + + "date-euro-asc": function ( a, b ) { + return a - b; + }, + + "date-euro-desc": function ( a, b ) { + return b - a; + } + + }); + //source https://cdn.datatables.net/plug-ins/1.10.12/type-detection/ip-address.js (modified) jQuery.fn.dataTableExt.aTypes.unshift( function ( sData ) diff --git a/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js b/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js index 57087ed5e8..7e145bf86e 100644 --- a/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js +++ b/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js @@ -75,7 +75,8 @@ define(function(require) { {"sWidth": "35px", "aTargets": [0]}, {"bVisible": true, "aTargets": SunstoneConfig.tabTableColumns(TAB_NAME)}, {"bVisible": false, "aTargets": ['_all']}, - {"sType": "file-size", "aTargets": [ 6 ] } + {"sType": "file-size", "aTargets": [ 6 ]}, + {"sType": "date-euro", "aTargets": [ 9 ]} ] } @@ -150,7 +151,7 @@ define(function(require) { Humanize.sizeFromMB(element.SIZE), state, OpenNebulaMarketPlaceApp.typeStr(element.TYPE), - Humanize.prettyTime(element.REGTIME), + Humanize.prettyTimeDatatable(element.REGTIME), element.MARKETPLACE, zone, (LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||''), diff --git a/src/sunstone/public/app/tabs/templates-tab/datatable-common.js b/src/sunstone/public/app/tabs/templates-tab/datatable-common.js index 15c5d861dd..6d5074d5ac 100644 --- a/src/sunstone/public/app/tabs/templates-tab/datatable-common.js +++ b/src/sunstone/public/app/tabs/templates-tab/datatable-common.js @@ -58,7 +58,8 @@ define(function(require) { {"bSortable": false, "aTargets": ["check"]}, {"sWidth": "35px", "aTargets": [0]}, {"bVisible": true, "aTargets": SunstoneConfig.tabTableColumns(tabId)}, - {"bVisible": false, "aTargets": ['_all']} + {"bVisible": false, "aTargets": ['_all']}, + {"sType": "date-euro", "aTargets": [ 5 ]} ] } @@ -118,7 +119,7 @@ define(function(require) { element.NAME, element.UNAME, element.GNAME, - Humanize.prettyTime(element.REGTIME), + Humanize.prettyTimeDatatable(element.REGTIME), (LabelsUtils.labelsStr(element[TEMPLATE_ATTR])||''), btoa(unescape(encodeURIComponent(JSON.stringify(search)))) ]; diff --git a/src/sunstone/public/app/utils/humanize.js b/src/sunstone/public/app/utils/humanize.js index b62a93ef40..cc3ca2def0 100644 --- a/src/sunstone/public/app/utils/humanize.js +++ b/src/sunstone/public/app/utils/humanize.js @@ -32,7 +32,8 @@ define(function(require) { 'prettyTime': _prettyTime, 'prettyTimeAxis': _prettyTimeAxis, 'prettyPrintJSON': _prettyPrintJSON, - 'prettyTimeAgo': _format_date + 'prettyTimeAgo': _format_date, + 'prettyTimeDatatable': _prettyTimeDatatable } /* @@ -240,6 +241,20 @@ define(function(require) { return str; } + function _prettyTimeDatatable(seconds) { + var d = new Date(); + d.setTime(seconds * 1000); + + var secs = _pad(d.getSeconds(), 2); + var hour = _pad(d.getHours(), 2); + var mins = _pad(d.getMinutes(), 2); + var day = _pad(d.getDate(), 2); + var month = _pad(d.getMonth() + 1, 2); //getMonths returns 0-11 + var year = d.getFullYear(); + + return day + "/" + month + "/" + year + " " + hour + ":" + mins + ":" + secs; + } + function _format_date(unix_timestamp) { var difference_in_seconds = (Math.round((new Date()).getTime() / 1000)) - unix_timestamp, current_date = new Date(unix_timestamp * 1000), minutes, hours; From f89decb42f0cbffa1b42faadb7e93047c3bcb147 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Mon, 24 Jul 2017 15:44:50 +0200 Subject: [PATCH 34/40] B #5256 Changed disk-resize to 'true' in cloud_vcenter view (#408) --- src/sunstone/etc/sunstone-views/cloud_vcenter.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/etc/sunstone-views/cloud_vcenter.yaml b/src/sunstone/etc/sunstone-views/cloud_vcenter.yaml index a6d21a787e..c01239fefe 100644 --- a/src/sunstone/etc/sunstone-views/cloud_vcenter.yaml +++ b/src/sunstone/etc/sunstone-views/cloud_vcenter.yaml @@ -85,7 +85,7 @@ tabs: # True to allow NIC customization network_select: true # True to allow DISK size customization - disk_resize: false + disk_resize: true settings-tab: panel_tabs: settings_info_tab: false From 1f6286b28f222563bc3a09d4f1aaa791426618fc Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Mon, 24 Jul 2017 15:46:12 +0200 Subject: [PATCH 35/40] Added TotalVMs and solved bug in VMGroups (#412) --- src/sunstone/public/app/tabs/vmgroup-tab.js | 3 ++- .../public/app/tabs/vmgroup-tab/datatable.js | 16 ++++++++++++++++ .../app/tabs/vmgroup-tab/utils/role-tab/html.hbs | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/sunstone/public/app/tabs/vmgroup-tab.js b/src/sunstone/public/app/tabs/vmgroup-tab.js index 171ac47a9c..5abdbbe893 100644 --- a/src/sunstone/public/app/tabs/vmgroup-tab.js +++ b/src/sunstone/public/app/tabs/vmgroup-tab.js @@ -42,7 +42,8 @@ define(function(require) { infoHeader: Locale.tr("VM Groups"), subheader: '\ '+Locale.tr("TOTAL")+'\ - ', +  \ + '+Locale.tr("TOTAL VMs")+'', resource: 'VMGroup', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/vmgroup-tab/datatable.js b/src/sunstone/public/app/tabs/vmgroup-tab/datatable.js index 7bd48480ea..df4ccd0056 100644 --- a/src/sunstone/public/app/tabs/vmgroup-tab/datatable.js +++ b/src/sunstone/public/app/tabs/vmgroup-tab/datatable.js @@ -80,6 +80,8 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following vm groups:") }; + this.totalVMGroups = 0; + this.totalVMs = 0; this.conf.searchDropdownHTML = SearchDropdown({tableId: this.dataTableId}); this.searchColumn = SEARCH_COLUMN; @@ -90,6 +92,8 @@ define(function(require) { Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -100,6 +104,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json[XML_ROOT]; var numVms = 0; + this.totalVMGroups++; for(role_index in element.ROLES.ROLE){ if(element.ROLES.ROLE[role_index].VMS){ @@ -108,6 +113,7 @@ define(function(require) { numVms += vms.length; } } + this.totalVMs += numVms; var search = { NAME: element.NAME, @@ -129,4 +135,14 @@ define(function(require) { ]; } + function _preUpdateView() { + this.totalVMGroups = 0; + this.totalVMs= 0; + } + + function _postUpdateView() { + $(".total_vmgroup").text(this.totalVMGroups); + $(".total_vms_vmgroup").text(this.totalVMs); + } + }); diff --git a/src/sunstone/public/app/tabs/vmgroup-tab/utils/role-tab/html.hbs b/src/sunstone/public/app/tabs/vmgroup-tab/utils/role-tab/html.hbs index 8252fca592..65fa52d772 100644 --- a/src/sunstone/public/app/tabs/vmgroup-tab/utils/role-tab/html.hbs +++ b/src/sunstone/public/app/tabs/vmgroup-tab/utils/role-tab/html.hbs @@ -33,7 +33,7 @@

-
+
From 4998103180b60581a7de73426288727dad0ed865 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Mon, 24 Jul 2017 15:46:32 +0200 Subject: [PATCH 36/40] Solved bug when Network Topology is empty (#413) --- src/sunstone/public/app/tabs/vnets-topology-tab.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/sunstone/public/app/tabs/vnets-topology-tab.js b/src/sunstone/public/app/tabs/vnets-topology-tab.js index 9312106b96..f77c3dd6ae 100644 --- a/src/sunstone/public/app/tabs/vnets-topology-tab.js +++ b/src/sunstone/public/app/tabs/vnets-topology-tab.js @@ -588,7 +588,9 @@ define(function(require) { _network.cluster(clusterOptionsByData); }); - _network.stabilize(); + if(_network){ + _network.stabilize(); + } } function _openVMs(){ @@ -604,10 +606,15 @@ define(function(require) { } }); - _network.stabilize(); + if(_network){ + _network.stabilize(); + } } function _fit(){ - _network.fit(); + + if(_network){ + _network.fit(); + } } }); From b9e9f9660f1bc463e782c81d09698e3c3861089e Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Mon, 24 Jul 2017 16:13:44 +0200 Subject: [PATCH 37/40] Added subheader in all resource-tab (#414) * Added total ACLs * Added total Zones * Added total Clusters * Added total Security Groups * Added total MarketPlaceApps * Added total MarketPlaces * Added total Files * Added total Images * Added total Datastores * Added total VRouters * Added total Templates * Added total Virtual Routers --- src/sunstone/public/app/tabs/acls-tab.js | 4 ++- .../public/app/tabs/acls-tab/datatable.js | 14 +++++++++++ src/sunstone/public/app/tabs/clusters-tab.js | 4 ++- .../public/app/tabs/clusters-tab/datatable.js | 14 +++++++++++ .../public/app/tabs/datastores-tab.js | 4 ++- .../app/tabs/datastores-tab/datatable.js | 25 +++++++++++++++++++ src/sunstone/public/app/tabs/files-tab.js | 4 ++- .../public/app/tabs/files-tab/datatable.js | 12 +++++++++ src/sunstone/public/app/tabs/images-tab.js | 3 ++- .../public/app/tabs/marketplaceapps-tab.js | 4 ++- .../app/tabs/marketplaceapps-tab/datatable.js | 14 +++++++++++ .../public/app/tabs/marketplaces-tab.js | 4 ++- .../app/tabs/marketplaces-tab/datatable.js | 13 ++++++++++ src/sunstone/public/app/tabs/secgroups-tab.js | 4 ++- .../app/tabs/secgroups-tab/datatable.js | 13 ++++++++++ src/sunstone/public/app/tabs/templates-tab.js | 4 ++- .../app/tabs/templates-tab/datatable.js | 13 ++++++++++ .../public/app/tabs/vrouter-templates-tab.js | 4 ++- .../tabs/vrouter-templates-tab/datatable.js | 13 ++++++++++ src/sunstone/public/app/tabs/vrouters-tab.js | 4 ++- .../public/app/tabs/vrouters-tab/datatable.js | 13 ++++++++++ src/sunstone/public/app/tabs/zones-tab.js | 4 ++- .../public/app/tabs/zones-tab/datatable.js | 14 +++++++++++ 23 files changed, 193 insertions(+), 12 deletions(-) diff --git a/src/sunstone/public/app/tabs/acls-tab.js b/src/sunstone/public/app/tabs/acls-tab.js index 8aab1829f7..0fc6acf447 100644 --- a/src/sunstone/public/app/tabs/acls-tab.js +++ b/src/sunstone/public/app/tabs/acls-tab.js @@ -40,7 +40,9 @@ define(function(require) { tabClass: "subTab", parentTab: "system-top-tab", listHeader: Locale.tr("Access Control Lists"), - subheader: ' ', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'Acl', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/acls-tab/datatable.js b/src/sunstone/public/app/tabs/acls-tab/datatable.js index ebf74a99f0..20582f92aa 100644 --- a/src/sunstone/public/app/tabs/acls-tab/datatable.js +++ b/src/sunstone/public/app/tabs/acls-tab/datatable.js @@ -57,6 +57,8 @@ define(function(require) { ] }; + this.totalACLs = 0; + this.columns = [ Locale.tr("ID"), Locale.tr("Applies to"), @@ -82,6 +84,8 @@ define(function(require) { Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -96,6 +100,8 @@ define(function(require) { var acl_array = _parseAclString(acl_string); + this.totalACLs++; + return [ '  ', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'Cluster', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/clusters-tab/datatable.js b/src/sunstone/public/app/tabs/clusters-tab/datatable.js index a0cfe9b52b..efcdc9c13b 100644 --- a/src/sunstone/public/app/tabs/clusters-tab/datatable.js +++ b/src/sunstone/public/app/tabs/clusters-tab/datatable.js @@ -76,12 +76,16 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following clusters:") }; + this.totalClusters = 0; + TabDataTable.call(this); } Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -91,6 +95,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json[XML_ROOT]; + this.totalClusters++; return [ ' '+Locale.tr("TOTAL")+' \ + '+Locale.tr("ON")+' \ + '+Locale.tr("OFF")+'', resource: 'Datastore', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/datastores-tab/datatable.js b/src/sunstone/public/app/tabs/datastores-tab/datatable.js index 554089c206..3f3f6e45af 100644 --- a/src/sunstone/public/app/tabs/datastores-tab/datatable.js +++ b/src/sunstone/public/app/tabs/datastores-tab/datatable.js @@ -106,12 +106,18 @@ define(function(require) { this.conf.searchDropdownHTML = SearchDropdown({tableId: this.dataTableId}); this.searchColumn = SEARCH_COLUMN; + this.totalDSs = 0; + this.totalON = 0; + this.totalOFF = 0; + TabDataTable.call(this); }; Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -121,6 +127,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json.DATASTORE; + this.totalDSs++; var clusters = '-'; if (element.CLUSTERS.ID != undefined){ @@ -129,6 +136,12 @@ define(function(require) { var state = OpenNebulaDatastore.stateStr(element.STATE); + if(state == "ON"){ + this.totalON++; + } else if(state == "OFF"){ + this.totalOFF++; + } + var search = { NAME: element.NAME, UNAME: element.UNAME, @@ -157,4 +170,16 @@ define(function(require) { btoa(unescape(encodeURIComponent(JSON.stringify(search)))) ]; } + + function _preUpdateView() { + this.totalDSs = 0; + this.totalON = 0; + this.totalOFF = 0; + } + + function _postUpdateView() { + $(".total_ds").text(this.totalDSs); + $(".total_on").text(this.totalON); + $(".total_off").text(this.totalOFF); + } }); diff --git a/src/sunstone/public/app/tabs/files-tab.js b/src/sunstone/public/app/tabs/files-tab.js index f98d97648c..0f6b574e1f 100644 --- a/src/sunstone/public/app/tabs/files-tab.js +++ b/src/sunstone/public/app/tabs/files-tab.js @@ -45,7 +45,9 @@ define(function(require) { parentTab: "storage-top-tab", listHeader: Locale.tr("Files"), infoHeader: Locale.tr("File"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'File', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/files-tab/datatable.js b/src/sunstone/public/app/tabs/files-tab/datatable.js index 1a728c1627..6b15a147d4 100644 --- a/src/sunstone/public/app/tabs/files-tab/datatable.js +++ b/src/sunstone/public/app/tabs/files-tab/datatable.js @@ -47,12 +47,15 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following files:") }; + this.totalFiles = 0; ImageCommonDataTable.call(this, RESOURCE, TAB_NAME, dataTableId, conf); }; Table.prototype = Object.create(ImageCommonDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -69,6 +72,15 @@ define(function(require) { return false; } + this.totalFiles++; return this.elementArrayCommon(element_json); } + + function _preUpdateView() { + this.totalFiles = 0; + } + + function _postUpdateView() { + $(".total_files").text(this.totalFiles); + } }); \ No newline at end of file diff --git a/src/sunstone/public/app/tabs/images-tab.js b/src/sunstone/public/app/tabs/images-tab.js index ef326fa65f..464d8d907e 100644 --- a/src/sunstone/public/app/tabs/images-tab.js +++ b/src/sunstone/public/app/tabs/images-tab.js @@ -50,7 +50,8 @@ define(function(require) { parentTab: "storage-top-tab", listHeader: Locale.tr("Images"), infoHeader: Locale.tr("Image"), - subheader: '', + subheader: ' '+Locale.tr("TOTAL")+' \ + '+Locale.tr("TOTAL SIZE")+'', resource: 'Image', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/marketplaceapps-tab.js b/src/sunstone/public/app/tabs/marketplaceapps-tab.js index 46570bf808..3b89870050 100644 --- a/src/sunstone/public/app/tabs/marketplaceapps-tab.js +++ b/src/sunstone/public/app/tabs/marketplaceapps-tab.js @@ -52,7 +52,9 @@ define(function(require) { parentTab: "storage-top-tab", listHeader: Locale.tr("Apps"), infoHeader: Locale.tr("App"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'MarketPlaceApp', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js b/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js index 7e145bf86e..445e18c4aa 100644 --- a/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js +++ b/src/sunstone/public/app/tabs/marketplaceapps-tab/datatable.js @@ -106,6 +106,8 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following appliances:") } + this.totalApps = 0; + this.conf.searchDropdownHTML = SearchDropdown({tableId: this.dataTableId}); this.searchColumn = SEARCH_COLUMN; @@ -115,6 +117,8 @@ define(function(require) { Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -128,6 +132,8 @@ define(function(require) { var state = OpenNebulaMarketPlaceApp.stateStr(element.STATE); var zone = OpenNebulaZone.getName(element.ZONE_ID); + this.totalApps++; + var search = { NAME: element.NAME, UNAME: element.UNAME, @@ -168,4 +174,12 @@ define(function(require) { return l; } + + function _preUpdateView() { + this.totalApps = 0; + } + + function _postUpdateView() { + $(".total_apps").text(this.totalApps); + } }); diff --git a/src/sunstone/public/app/tabs/marketplaces-tab.js b/src/sunstone/public/app/tabs/marketplaces-tab.js index 9bb60ad9f9..98773d41a7 100644 --- a/src/sunstone/public/app/tabs/marketplaces-tab.js +++ b/src/sunstone/public/app/tabs/marketplaces-tab.js @@ -51,7 +51,9 @@ define(function(require) { parentTab: "storage-top-tab", listHeader: Locale.tr("MarketPlaces"), infoHeader: Locale.tr("MarketPlace"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'MarketPlace', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/marketplaces-tab/datatable.js b/src/sunstone/public/app/tabs/marketplaces-tab/datatable.js index 697a05de00..2ae1176186 100644 --- a/src/sunstone/public/app/tabs/marketplaces-tab/datatable.js +++ b/src/sunstone/public/app/tabs/marketplaces-tab/datatable.js @@ -104,12 +104,16 @@ define(function(require) { this.conf.searchDropdownHTML = SearchDropdown({tableId: this.dataTableId}); this.searchColumn = SEARCH_COLUMN; + this.totalMarkets = 0; + TabDataTable.call(this); }; Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -119,6 +123,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json[XML_ROOT]; + this.totalMarkets++; var zone = OpenNebulaZone.getName(element.ZONE_ID); @@ -156,4 +161,12 @@ define(function(require) { return l; } + + function _preUpdateView() { + this.totalMarkets = 0; + } + + function _postUpdateView() { + $(".total_markets").text(this.totalMarkets); + } }); diff --git a/src/sunstone/public/app/tabs/secgroups-tab.js b/src/sunstone/public/app/tabs/secgroups-tab.js index f1995e67b5..682944597c 100644 --- a/src/sunstone/public/app/tabs/secgroups-tab.js +++ b/src/sunstone/public/app/tabs/secgroups-tab.js @@ -48,7 +48,9 @@ define(function(require) { parentTab: "network-top-tab", listHeader: Locale.tr("Security Groups"), infoHeader: Locale.tr("Security Group"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'SecurityGroup', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/secgroups-tab/datatable.js b/src/sunstone/public/app/tabs/secgroups-tab/datatable.js index 72cc1baf42..3d556bddd8 100644 --- a/src/sunstone/public/app/tabs/secgroups-tab/datatable.js +++ b/src/sunstone/public/app/tabs/secgroups-tab/datatable.js @@ -78,6 +78,8 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following security groups:") }; + this.totalSecGroups = 0; + this.conf.searchDropdownHTML = SearchDropdown({tableId: this.dataTableId}); this.searchColumn = SEARCH_COLUMN; @@ -87,6 +89,8 @@ define(function(require) { Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -96,6 +100,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json[XML_ROOT]; + this.totalSecGroups++; var search = { NAME: element.NAME, @@ -115,4 +120,12 @@ define(function(require) { btoa(unescape(encodeURIComponent(JSON.stringify(search)))) ]; } + + function _preUpdateView() { + this.totalSecGroups = 0; + } + + function _postUpdateView() { + $(".total_secgroups").text(this.totalSecGroups); + } }); diff --git a/src/sunstone/public/app/tabs/templates-tab.js b/src/sunstone/public/app/tabs/templates-tab.js index de66524bfc..986694b0d3 100644 --- a/src/sunstone/public/app/tabs/templates-tab.js +++ b/src/sunstone/public/app/tabs/templates-tab.js @@ -50,7 +50,9 @@ define(function(require) { parentTab: "templates-top-tab", listHeader: Locale.tr("VM Templates"), infoHeader: Locale.tr("VM Template"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'Template', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/templates-tab/datatable.js b/src/sunstone/public/app/tabs/templates-tab/datatable.js index d66aecd846..e195bb6709 100644 --- a/src/sunstone/public/app/tabs/templates-tab/datatable.js +++ b/src/sunstone/public/app/tabs/templates-tab/datatable.js @@ -34,11 +34,14 @@ define(function(require) { function Table(dataTableId, conf) { CommonDataTable.call(this, RESOURCE, TAB_NAME, dataTableId, conf); + this.totalTemplates = 0; }; Table.prototype = Object.create(CommonDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -55,6 +58,16 @@ define(function(require) { return false; } + this.totalTemplates++; + return this.elementArrayCommon(element_json); } + + function _preUpdateView() { + this.totalTemplates = 0; + } + + function _postUpdateView() { + $(".total_templates").text(this.totalTemplates); + } }); diff --git a/src/sunstone/public/app/tabs/vrouter-templates-tab.js b/src/sunstone/public/app/tabs/vrouter-templates-tab.js index fc70ead3de..6a901988b9 100644 --- a/src/sunstone/public/app/tabs/vrouter-templates-tab.js +++ b/src/sunstone/public/app/tabs/vrouter-templates-tab.js @@ -48,7 +48,9 @@ define(function(require) { parentTab: "templates-top-tab", listHeader: Locale.tr("Virtual Router VM Templates"), infoHeader: Locale.tr("Virtual Router VM Template"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'VirtualRouterTemplate', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/vrouter-templates-tab/datatable.js b/src/sunstone/public/app/tabs/vrouter-templates-tab/datatable.js index e25c2d13a3..dc9c10c931 100644 --- a/src/sunstone/public/app/tabs/vrouter-templates-tab/datatable.js +++ b/src/sunstone/public/app/tabs/vrouter-templates-tab/datatable.js @@ -34,11 +34,14 @@ define(function(require) { function Table(dataTableId, conf) { CommonDataTable.call(this, RESOURCE, TAB_NAME, dataTableId, conf); + this.totalVRouters = 0; }; Table.prototype = Object.create(CommonDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -55,6 +58,16 @@ define(function(require) { return false; } + this.totalVRouters++; + return this.elementArrayCommon(element_json); } + + function _preUpdateView() { + this.totalVRouters = 0; + } + + function _postUpdateView() { + $(".total_vrouters").text(this.totalVRouters); + } }); diff --git a/src/sunstone/public/app/tabs/vrouters-tab.js b/src/sunstone/public/app/tabs/vrouters-tab.js index b59efbc9da..beb6e76713 100644 --- a/src/sunstone/public/app/tabs/vrouters-tab.js +++ b/src/sunstone/public/app/tabs/vrouters-tab.js @@ -49,7 +49,9 @@ define(function(require) { parentTab: "instances-top-tab", listHeader: Locale.tr("Virtual Routers"), infoHeader: Locale.tr("Virtual Router"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'VirtualRouter', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/vrouters-tab/datatable.js b/src/sunstone/public/app/tabs/vrouters-tab/datatable.js index 7a289d10f7..59b2175aa7 100644 --- a/src/sunstone/public/app/tabs/vrouters-tab/datatable.js +++ b/src/sunstone/public/app/tabs/vrouters-tab/datatable.js @@ -78,6 +78,8 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following virtual routers:") }; + this.totalRouters = 0; + this.conf.searchDropdownHTML = SearchDropdown({tableId: this.dataTableId}); this.searchColumn = SEARCH_COLUMN; @@ -87,6 +89,8 @@ define(function(require) { Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -96,6 +100,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json[XML_ROOT]; + this.totalRouters++; var search = { NAME: element.NAME, @@ -115,4 +120,12 @@ define(function(require) { btoa(unescape(encodeURIComponent(JSON.stringify(search)))) ]; } + + function _preUpdateView() { + this.totalRouters = 0; + } + + function _postUpdateView() { + $(".total_routers").text(this.totalRouters); + } }); diff --git a/src/sunstone/public/app/tabs/zones-tab.js b/src/sunstone/public/app/tabs/zones-tab.js index a17d7c0026..787629a40f 100644 --- a/src/sunstone/public/app/tabs/zones-tab.js +++ b/src/sunstone/public/app/tabs/zones-tab.js @@ -43,7 +43,9 @@ define(function(require) { parentTab: "infrastructure-top-tab", listHeader: Locale.tr("Zones"), infoHeader: Locale.tr("Zone"), - subheader: '', + subheader: '\ + '+Locale.tr("TOTAL")+'\ + ', resource: 'Zone', buttons: Buttons, actions: Actions, diff --git a/src/sunstone/public/app/tabs/zones-tab/datatable.js b/src/sunstone/public/app/tabs/zones-tab/datatable.js index 6b239b23a5..8233a91038 100644 --- a/src/sunstone/public/app/tabs/zones-tab/datatable.js +++ b/src/sunstone/public/app/tabs/zones-tab/datatable.js @@ -74,12 +74,16 @@ define(function(require) { "you_selected_multiple": Locale.tr("You selected the following Zones:") }; + this.totalZones = 0; + TabDataTable.call(this); }; Table.prototype = Object.create(TabDataTable.prototype); Table.prototype.constructor = Table; Table.prototype.elementArray = _elementArray; + Table.prototype.preUpdateView = _preUpdateView; + Table.prototype.postUpdateView = _postUpdateView; return Table; @@ -89,6 +93,7 @@ define(function(require) { function _elementArray(element_json) { var element = element_json.ZONE; + this.totalZones++; return [ ' Date: Wed, 26 Jul 2017 11:02:21 +0200 Subject: [PATCH 38/40] B #5256 Added actions panel in VM Template yamls (#416) --- src/sunstone/etc/sunstone-views/admin_vcenter.yaml | 1 + src/sunstone/etc/sunstone-views/groupadmin.yaml | 1 + src/sunstone/etc/sunstone-views/groupadmin_vcenter.yaml | 1 + src/sunstone/etc/sunstone-views/user.yaml | 1 + 4 files changed, 4 insertions(+) diff --git a/src/sunstone/etc/sunstone-views/admin_vcenter.yaml b/src/sunstone/etc/sunstone-views/admin_vcenter.yaml index 3c9b6ed7dc..75652a75c7 100644 --- a/src/sunstone/etc/sunstone-views/admin_vcenter.yaml +++ b/src/sunstone/etc/sunstone-views/admin_vcenter.yaml @@ -230,6 +230,7 @@ tabs: features: true input_output: true context: true + actions: true scheduling: true hybrid: true vmgroup: true diff --git a/src/sunstone/etc/sunstone-views/groupadmin.yaml b/src/sunstone/etc/sunstone-views/groupadmin.yaml index 1795a6e60d..b778cae901 100644 --- a/src/sunstone/etc/sunstone-views/groupadmin.yaml +++ b/src/sunstone/etc/sunstone-views/groupadmin.yaml @@ -231,6 +231,7 @@ tabs: features: true input_output: true context: true + actions: true scheduling: true hybrid: true vmgroup: true diff --git a/src/sunstone/etc/sunstone-views/groupadmin_vcenter.yaml b/src/sunstone/etc/sunstone-views/groupadmin_vcenter.yaml index b772b8e9b0..ed154a7be6 100644 --- a/src/sunstone/etc/sunstone-views/groupadmin_vcenter.yaml +++ b/src/sunstone/etc/sunstone-views/groupadmin_vcenter.yaml @@ -225,6 +225,7 @@ tabs: features: true input_output: true context: true + actions: true scheduling: true hybrid: true vmgroup: true diff --git a/src/sunstone/etc/sunstone-views/user.yaml b/src/sunstone/etc/sunstone-views/user.yaml index d7c8af53a0..c3dfc75c50 100644 --- a/src/sunstone/etc/sunstone-views/user.yaml +++ b/src/sunstone/etc/sunstone-views/user.yaml @@ -230,6 +230,7 @@ tabs: features: true input_output: true context: true + actions: true scheduling: false hybrid: true vmgroup: true From 843446a1134cbdb11f8740a1b7c43cb74c245a72 Mon Sep 17 00:00:00 2001 From: Abel Coronado Date: Wed, 26 Jul 2017 11:04:49 +0200 Subject: [PATCH 39/40] R #5283 Added scroll bar in Sunstone VM Log (#417) --- src/sunstone/public/app/tabs/vms-tab/panels/log.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sunstone/public/app/tabs/vms-tab/panels/log.js b/src/sunstone/public/app/tabs/vms-tab/panels/log.js index a43f524549..9ad8cd3aba 100644 --- a/src/sunstone/public/app/tabs/vms-tab/panels/log.js +++ b/src/sunstone/public/app/tabs/vms-tab/panels/log.js @@ -59,7 +59,7 @@ define(function(require) { function _html() { return '
' + - '
' + + '
' + '
' + '' + '' + From 6368bb51fcafe56f4be1cdaf1392d39d0fc89241 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 27 Jul 2017 12:51:41 +0200 Subject: [PATCH 40/40] F #4977: Move missing monitor map logic to monitor_action() --- include/MarketPlaceAppPool.h | 53 +++++++++--------------- src/market/MarketPlaceAppPool.cc | 57 ++++++++++++++++++++------ src/market/MarketPlaceManagerDriver.cc | 57 +++++++++++++------------- 3 files changed, 93 insertions(+), 74 deletions(-) diff --git a/include/MarketPlaceAppPool.h b/include/MarketPlaceAppPool.h index 01c80af4d9..d66f674a09 100644 --- a/include/MarketPlaceAppPool.h +++ b/include/MarketPlaceAppPool.h @@ -73,13 +73,14 @@ public: * @param template to generate app with the from_template64 function * @param mp_id of the MarketPlace to store de App * @param mp_name of the MarketPlace + * @param app_id of the imported app * @param error_str Returns the error reason, if any * * @return the oid assigned to the object, -1 in case of failure, -2 * already imported */ int import(const std::string& t64, int mp_id, const std::string& mp_name, - std::string& error_str); + int& app_id, std::string& error_str); /** * Function to get a MarketPlaceApp from the pool @@ -147,43 +148,29 @@ public: }; /** - * Erease map element + * Check an element into map + * @param map_id of the app + * @return true if the app has to be deleted */ - void drop_map_check(const std::string& name){ - if (map_check.find( name ) != map_check.end()){ - map::iterator it; - it=map_check.find(name); - map_check.erase (it); - } - } + bool test_map_check(int map_id); /** - * Check an element into map + * Resets the counter of missing monitors of an app + * @param app_id of the app */ - bool test_map_check(const std::string& name){ - map_check[name]++; - if (map_check[name] > 0){ - return true; - } - return false; - } -private: - map map_check; + void reset_map_check(int app_id); - - void insert_map_check(const std::string& name){ - map_check.insert(make_pair(name, -1)); - } - void reset_map_check(const std::string& name){ - if (name != "") { - if (map_check.find( name ) != map_check.end()){ - map_check[name] = -1; - } - else{ - insert_map_check(name); - } - } - } +private: + + /** + * Hash to store the number of times an app was missing from monitor data + */ + map map_check; + + /** + * Max number of monitor that an app may be missing before deleting it + */ + static const int MAX_MISSING_MONITORS; }; #endif /*MARKETPLACE_POOL_H_*/ diff --git a/src/market/MarketPlaceAppPool.cc b/src/market/MarketPlaceAppPool.cc index 68c2d64e7e..e80944b4ca 100644 --- a/src/market/MarketPlaceAppPool.cc +++ b/src/market/MarketPlaceAppPool.cc @@ -128,11 +128,6 @@ int MarketPlaceAppPool:: allocate( *oid = PoolSQL::allocate(mp, error_str); - // ------------------------------------------------------------------------ - // Insert id into map_check - // -------------------------------------------------------------------------- - insert_map_check(name); - return *oid; error_duplicated: @@ -188,8 +183,6 @@ int MarketPlaceAppPool::drop(PoolObjectSQL * objsql, std::string& error_msg) return 0; } - drop_map_check(objsql->get_name()); - return PoolSQL::drop(objsql, error_msg); } @@ -197,7 +190,7 @@ int MarketPlaceAppPool::drop(PoolObjectSQL * objsql, std::string& error_msg) /* -------------------------------------------------------------------------- */ int MarketPlaceAppPool::import(const std::string& t64, int mp_id, - const std::string& mp_name, std::string& error_str) + const std::string& mp_name, int& app_id, std::string& error_str) { // ------------------------------------------------------------------------- // Build the marketplace app object @@ -236,7 +229,8 @@ int MarketPlaceAppPool::import(const std::string& t64, int mp_id, if( mp_aux != 0 ) //Marketplace app already imported { - reset_map_check(app->name); + app_id = mp_aux->oid; + if ( mp_aux->version != app->version || mp_aux->md5 != app->md5 ) { mp_aux->from_template64(t64, error_str); @@ -256,15 +250,17 @@ int MarketPlaceAppPool::import(const std::string& t64, int mp_id, // ------------------------------------------------------------------------- if (Nebula::instance().is_federation_slave()) { - int oid = master_allocate(app, error_str); + app_id = master_allocate(app, error_str); app->lock(); delete app; - return oid; + return app_id; } - insert_map_check(app->name); - return PoolSQL::allocate(app, error_str); + + app_id = PoolSQL::allocate(app, error_str); + + return app_id; } /* -------------------------------------------------------------------------- */ @@ -316,4 +312,39 @@ int MarketPlaceAppPool::update(PoolObjectSQL * objsql) /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ +const int MarketPlaceAppPool::MAX_MISSING_MONITORS = 3; +bool MarketPlaceAppPool::test_map_check(int app_id) +{ + map::iterator it = map_check.find(app_id); + + if ( it == map_check.end() ) + { + return false; + } + + it->second++; + + bool to_delete = it->second >= MAX_MISSING_MONITORS; + + if ( to_delete ) + { + map_check.erase(it); + } + + return to_delete; +} + +void MarketPlaceAppPool::reset_map_check(int app_id) +{ + map::iterator it = map_check.find(app_id); + + if ( it == map_check.end() ) + { + map_check.insert(make_pair(app_id, -1)); + } + else + { + it->second = -1; + } +} diff --git a/src/market/MarketPlaceManagerDriver.cc b/src/market/MarketPlaceManagerDriver.cc index 15e3ea4e42..695391389d 100644 --- a/src/market/MarketPlaceManagerDriver.cc +++ b/src/market/MarketPlaceManagerDriver.cc @@ -120,7 +120,6 @@ static void monitor_action( return; } - std::string name; MarketPlace * market = marketpool->get(id, true); if (market == 0 ) @@ -128,7 +127,8 @@ static void monitor_action( return; } - name = market->get_name(); + set apps_mp = market->get_marketapp_ids(); + std::string name = market->get_name(); market->update_monitor(monitor_data); @@ -143,7 +143,8 @@ static void monitor_action( for (int i=0; i< num ; i++) { - int rc = apppool->import(apps[i]->value(), id, name, err); + int app_id; + int rc = apppool->import(apps[i]->value(), id, name, app_id, err); if ( rc == -1 ) { @@ -162,37 +163,37 @@ static void monitor_action( market->unlock(); } } + + apppool->reset_map_check(app_id); + + apps_mp.erase(app_id); } - MarketPlaceApp *mp_app = nullptr; - std::string error; - std::string source; - int rc_del; - market = marketpool->get(id, true); - set apps_mp = market->get_marketapp_ids(); - market->unlock(); - for (set::iterator i = apps_mp.begin(); i != apps_mp.end(); i++) { - mp_app = apppool->get(*i, true); - if ( mp_app != 0 ) - { - if(apppool->test_map_check(mp_app->get_name())){ //delete app - market = marketpool->get(id, true); + for (set::iterator i = apps_mp.begin(); i != apps_mp.end(); ++i) + { + if (apppool->test_map_check(*i)) //delete app + { + std::string error; - source = mp_app->get_source(); - rc_del = apppool->drop(mp_app, error); + MarketPlaceApp * app = apppool->get(*i, true); - market->del_marketapp(*i); - marketpool->update(market); - - market->unlock(); - if ( rc_del < 0 ) - { - oss << " Error removing app from DB: " << error - << ". Remove app manually, source is: " << source; - } + if ( app == 0 ) + { + continue; } + + rc = apppool->drop(app, error); + + app->unlock(); + + market = marketpool->get(id, true); + + market->del_marketapp(*i); + + marketpool->update(market); + + market->unlock(); } - mp_app->unlock(); } oss << "Marketplace " << name << " (" << id << ") successfully monitored.";