From fe5595e9aebfc767cd940e0c215ad924fab89fb4 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 27 Jul 2012 08:44:17 +0200 Subject: [PATCH 01/11] rbd: Small JavaScript fix --- ui/scripts/sharedFunctions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/scripts/sharedFunctions.js b/ui/scripts/sharedFunctions.js index c4cf58c86e5..a81c4270b21 100644 --- a/ui/scripts/sharedFunctions.js +++ b/ui/scripts/sharedFunctions.js @@ -482,8 +482,8 @@ function rbdURL(monitor, pool, id, secret) { Replace the + and / symbols by - and _ to have URL-safe base64 going to the API It's hacky, but otherwise we'll confuse java.net.URI which splits the incoming URI */ - secret = str.replace("+", "-"); - secret = str.replace("/", "_"); + secret = secret.replace("+", "-"); + secret = secret.replace("/", "_"); if (id != null && secret != null) { monitor = id + ":" + secret + "@" + monitor; From 38a140ecb465411a698c005ae5ac2f41d82bf6e6 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 27 Jul 2012 08:53:44 +0200 Subject: [PATCH 02/11] setup: Update 3.0.3 to 4.0.0 SQL update file I noticed that we have pending changes for the resource tags and Nicira integration. Adding them as a precaution, so they don't get lost. --- setup/db/db/schema-303to40.sql | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/setup/db/db/schema-303to40.sql b/setup/db/db/schema-303to40.sql index 87dd1d3c789..01710b10736 100644 --- a/setup/db/db/schema-303to40.sql +++ b/setup/db/db/schema-303to40.sql @@ -19,4 +19,45 @@ -- Schema upgrade from 3.0.3 to 4.0.0; --; +# RBD Primary Storage pool support (commit: 406fd95d87bfcdbb282d65589ab1fb6e9fd0018a) ALTER TABLE `storage_pool` ADD `user_info` VARCHAR( 255 ) NULL COMMENT 'Authorization information for the storage pool. Used by network filesystems' AFTER `host_address`; + +# Resource tags (commit: 62d45b9670520a1ee8b520509393d4258c689b50) +CREATE TABLE `cloud`.`resource_tags` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `key` varchar(255), + `value` varchar(255), + `resource_id` bigint unsigned NOT NULL, + `resource_uuid` varchar(40), + `resource_type` varchar(255), + `customer` varchar(255), + `domain_id` bigint unsigned NOT NULL COMMENT 'foreign key to domain id', + `account_id` bigint unsigned NOT NULL COMMENT 'owner of this network', + PRIMARY KEY (`id`), + CONSTRAINT `fk_tags__account_id` FOREIGN KEY(`account_id`) REFERENCES `account`(`id`), + CONSTRAINT `fk_tags__domain_id` FOREIGN KEY(`domain_id`) REFERENCES `domain`(`id`), + UNIQUE `i_tags__resource_id__resource_type__key`(`resource_id`, `resource_type`, `key`), + CONSTRAINT `uc_resource_tags__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +# Nicira Integration (commit: 79c7da07abd4294f150851aa0c2d06a28564c5a9) +CREATE TABLE `cloud`.`external_nicira_nvp_devices` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `uuid` varchar(255) UNIQUE, + `physical_network_id` bigint unsigned NOT NULL COMMENT 'id of the physical network in to which nicira nvp device is added', + `provider_name` varchar(255) NOT NULL COMMENT 'Service Provider name corresponding to this nicira nvp device', + `device_name` varchar(255) NOT NULL COMMENT 'name of the nicira nvp device', + `host_id` bigint unsigned NOT NULL COMMENT 'host id coresponding to the external nicira nvp device', + PRIMARY KEY (`id`), + CONSTRAINT `fk_external_nicira_nvp_devices__host_id` FOREIGN KEY (`host_id`) REFERENCES `host`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_external_nicira_nvp_devices__physical_network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`nicira_nvp_nic_map` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id', + `logicalswitch` varchar(255) NOT NULL COMMENT 'nicira uuid of logical switch this port is provisioned on', + `logicalswitchport` varchar(255) UNIQUE COMMENT 'nicira uuid of this logical switch port', + `nic` varchar(255) UNIQUE COMMENT 'cloudstack uuid of the nic connected to this logical switch port', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; From 1013a8329930831b211f8cedca31ff9f3f7b1941 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 27 Jul 2012 09:01:15 +0200 Subject: [PATCH 03/11] agent: Remove cloud-cleanup.conf for Ubuntu This is a very dangerous file. Although we do not package it, it would be very dangerous to do so. If this file would be present on a HyperVisor it would cause all instances to be stopped on a libvirt restart. There is no need for stopping all instances when libvirt is being stopped (or restarted). --- .../ubuntu/SYSCONFDIR/init/cloud-cleanup.conf | 32 ------------------- 1 file changed, 32 deletions(-) delete mode 100644 agent/distro/ubuntu/SYSCONFDIR/init/cloud-cleanup.conf diff --git a/agent/distro/ubuntu/SYSCONFDIR/init/cloud-cleanup.conf b/agent/distro/ubuntu/SYSCONFDIR/init/cloud-cleanup.conf deleted file mode 100644 index 71131e7c55c..00000000000 --- a/agent/distro/ubuntu/SYSCONFDIR/init/cloud-cleanup.conf +++ /dev/null @@ -1,32 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -description "Stop CloudStack VMs on shutdown" -author "Manuel Amador (Rudd-O) " - -start on stopping libvirt-bin - -task -script - curr_runlevel=`runlevel | tail -c 2` - if [ "$curr_runlevel" = "6" -o "$curr_runlevel" = "0" ] ; then - for a in `virsh list | awk ' /^ +[0-9]+ [vri]-([0-9]+?)-/ { print $2 } '` ; do - echo Destroying CloudStack VM $a - virsh destroy $a - done - fi -end script From b10a6196355df655800859adea8760a662b288a5 Mon Sep 17 00:00:00 2001 From: olgasmola Date: Fri, 27 Jul 2012 15:36:58 +0300 Subject: [PATCH 04/11] CS-15518: Fix password field garbling on login screen. --- ui/scripts/ui-custom/login.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/ui/scripts/ui-custom/login.js b/ui/scripts/ui-custom/login.js index 72b3c6c728a..20e6abff2b2 100644 --- a/ui/scripts/ui-custom/login.js +++ b/ui/scripts/ui-custom/login.js @@ -38,6 +38,17 @@ $login.appendTo('html body'); $('html body').addClass('login'); + // Remove label if field was auto filled + $.each($form.find('label'), function() { + var $label = $(this); + var $input = $form.find('input').filter(function() { + return $(this).attr('name') == $label.attr('for'); + }); + if ($input.val()) { + $label.hide(); + } + }); + // Form validation $form.validate(); From b7d68ac5d5eb287a5b57694fa6ddf8fddb1b033c Mon Sep 17 00:00:00 2001 From: olgasmola Date: Fri, 27 Jul 2012 16:27:59 +0300 Subject: [PATCH 05/11] CS-15325: Fix selected name of user from the drop down list overlay. --- ui/css/cloudstack3.css | 2 ++ ui/scripts/ui-custom/login.js | 19 +++++++++++++------ ui/scripts/ui/core.js | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/ui/css/cloudstack3.css b/ui/css/cloudstack3.css index a60e4807ca2..876d6633530 100644 --- a/ui/css/cloudstack3.css +++ b/ui/css/cloudstack3.css @@ -280,6 +280,8 @@ body.login { .login .fields .field label.error { color: #FF0000; float: right; + left: 204px; + top: 0; } .login .fields input { diff --git a/ui/scripts/ui-custom/login.js b/ui/scripts/ui-custom/login.js index 20e6abff2b2..c092b82ec0e 100644 --- a/ui/scripts/ui-custom/login.js +++ b/ui/scripts/ui-custom/login.js @@ -53,7 +53,7 @@ $form.validate(); // Form label behavior - $inputs.bind('keydown keyup focus blur', function(event) { + $inputs.bind('keydown focus click blur', function(event) { var $target = $(event.target); var $label = $form.find('label').filter(function() { return $(this).attr('for') == $target.attr('name'); @@ -63,11 +63,16 @@ $label.hide(); return true; - } else { - if (!$target.val()) { + } else if (event.type == 'blur') { + if ($target.hasClass('first-input')) { + $target.removeClass('first-input'); + } + if (!$(this).val()) { $label.show(); - } else { - $label.hide(); + } + } else { + if (!$target.hasClass('first-input')) { + $label.hide(); } } @@ -79,11 +84,13 @@ // Labels cause related input to be focused $login.find('label').click(function() { var $input = $inputs.filter('[name=' + $(this).attr('for') + ']'); + var $label = $(this); $input.focus(); + $label.hide(); }); - $inputs.filter(':first').focus(); + $inputs.filter(':first').addClass('first-input').focus(); // Login action $login.find('input[type=submit]').click(function() { diff --git a/ui/scripts/ui/core.js b/ui/scripts/ui/core.js index b7ffdba2328..0c6b4e744c7 100644 --- a/ui/scripts/ui/core.js +++ b/ui/scripts/ui/core.js @@ -352,7 +352,7 @@ // Check if target should be hovered function checkHoveredLabel($target) { var $multiWizard = $('div.ui-dialog div.multi-wizard'); - if ($target.is('label[for]') || + if (($target.is('label[for]') && !$target.parents('body.login')) || ($multiWizard.size() && ($target.is('.multi-wizard label') && $target.prev('input[type="radio"],input[type="checkbox"]').size()) || ($target.is('.multi-wizard .select-desc div.name') && $target.parent('div.select-desc').prev('input[type="radio"],input[type="checkbox"]').size()) From c1989a5e5f27751d646fb1eb41ace45ea05a9762 Mon Sep 17 00:00:00 2001 From: olgasmola Date: Fri, 27 Jul 2012 16:36:02 +0300 Subject: [PATCH 06/11] Fix build script typo. --- plugins/deployment-planners/user-concentrated-pod/build.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/deployment-planners/user-concentrated-pod/build.xml b/plugins/deployment-planners/user-concentrated-pod/build.xml index 29d4595b4a2..d63f33476b3 100755 --- a/plugins/deployment-planners/user-concentrated-pod/build.xml +++ b/plugins/deployment-planners/user-concentrated-pod/build.xml @@ -105,7 +105,7 @@ - + From 7fc3adbacc74850634b6b926d1552cfa00ea0bea Mon Sep 17 00:00:00 2001 From: olgasmola Date: Fri, 27 Jul 2012 17:32:54 +0300 Subject: [PATCH 07/11] CS-15349: Fix incorrect result when Make owner in New project/Add account. --- ui/scripts/projects.js | 28 ++++++++++++++++++++++++++-- ui/scripts/ui/widgets/multiEdit.js | 6 ++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/ui/scripts/projects.js b/ui/scripts/projects.js index 2ece194e014..cbbb4cef8a2 100644 --- a/ui/scripts/projects.js +++ b/ui/scripts/projects.js @@ -15,6 +15,7 @@ // specific language governing permissions and limitations // under the License. (function(cloudStack) { + var getProjectAdmin; cloudStack.projects = { requireInvitation: function(args) { return g_capabilities.projectinviterequired; @@ -447,12 +448,28 @@ return ['destroy']; } - if (args.context.multiRule[0].role != 'Admin') { + if (args.context.multiRule[0].role != 'Admin' && + (cloudStack.context.users[0].account == getProjectAdmin || isAdmin() || isDomainAdmin())) { // This is for the new project wizard: check if current logged in User is the Project Owner return args.context.actions; } return []; }, + readOnlyCheck: function(args) { // check if current logged in User is the Project Owner + if (isAdmin() || isDomainAdmin()) + return true; + + var projectOwner, currentUser = cloudStack.context.users[0].account; + $(args.data).each(function() { + var data = this; + if (data.role == 'Admin') + projectOwner = data.username; + }); + if (projectOwner == currentUser) + return true; + + return false; + }, actions: { destroy: { label: 'label.remove.project.account', @@ -497,7 +514,12 @@ success: function(data) { args.response.success({ _custom: { - jobId: data.updateprojectresponse.jobid + jobId: data.updateprojectresponse.jobid, + onComplete: function(){ + setTimeout(function() { + $(window).trigger('cloudStack.fullRefresh'); + }, 500); + } }, notification: { label: 'label.make.project.owner', @@ -522,6 +544,8 @@ success: function(data) { args.response.success({ data: $.map(data.listprojectaccountsresponse.projectaccount, function(elem) { + if (elem.role == 'Owner' || elem.role == 'Admin') + getProjectAdmin = elem.account; return { id: elem.accountid, role: elem.role, diff --git a/ui/scripts/ui/widgets/multiEdit.js b/ui/scripts/ui/widgets/multiEdit.js index 140b889a76b..93342141425 100644 --- a/ui/scripts/ui/widgets/multiEdit.js +++ b/ui/scripts/ui/widgets/multiEdit.js @@ -675,6 +675,7 @@ var context = args.context; var ignoreEmptyFields = args.ignoreEmptyFields; var actionPreFilter = args.actionPreFilter; + var readOnlyCheck = args.readOnlyCheck; var $thead = $('').appendTo( $('').appendTo($inputTable) @@ -935,6 +936,11 @@ ).appendTo($dataBody); }); + if (readOnlyCheck && !readOnlyCheck(args)) { + $multi.find('th.add-user, td.add-user').detach(); + $multiForm.find('tbody').detach(); + } + _medit.refreshItemWidths($multi); }, error: cloudStack.dialog.error From 7fbd612d69a230cf594cc290858ba409113dea7f Mon Sep 17 00:00:00 2001 From: olgasmola Date: Fri, 27 Jul 2012 18:23:07 +0300 Subject: [PATCH 08/11] CS-15317: Fix operations with accounts on the Project tab after making another account project owner. --- ui/scripts/projects.js | 31 ++++++++++++++++-- ui/scripts/ui/widgets/detailView.js | 50 ++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 17 deletions(-) diff --git a/ui/scripts/projects.js b/ui/scripts/projects.js index cbbb4cef8a2..293a2b01105 100644 --- a/ui/scripts/projects.js +++ b/ui/scripts/projects.js @@ -15,7 +15,7 @@ // specific language governing permissions and limitations // under the License. (function(cloudStack) { - var getProjectAdmin; + var getProjectAdmin, selectedProjectObj; cloudStack.projects = { requireInvitation: function(args) { return g_capabilities.projectinviterequired; @@ -518,6 +518,9 @@ onComplete: function(){ setTimeout(function() { $(window).trigger('cloudStack.fullRefresh'); + if (isUser()) { + $(window).trigger('cloudStack.detailsRefresh'); + } }, 500); } }, @@ -659,6 +662,30 @@ }, detailView: { + updateContext: function (args) { + var project; + var projectID = args.context.projects[0].id; + var url = 'listProjects'; + if (isDomainAdmin()) { + url += '&domainid=' + args.context.users[0].domainid; + } + $.ajax({ + url: createURL(url), + data: { + listAll: true, + id: projectID + }, + async: false, + success: function(json) { + project = json.listprojectsresponse.project[0]; // override project after update owner + } + }); + selectedProjectObj = project; + + return { + projects: [project] + }; + }, actions: { edit: { label: 'label.edit', @@ -782,7 +809,7 @@ }, tabFilter: function(args) { - var project = args.context.projects[0]; + var project = selectedProjectObj; var projectOwner = project.account; var currentAccount = args.context.users[0].account; var hiddenTabs = []; diff --git a/ui/scripts/ui/widgets/detailView.js b/ui/scripts/ui/widgets/detailView.js index b792bcf32ac..eb39b80c05a 100644 --- a/ui/scripts/ui/widgets/detailView.js +++ b/ui/scripts/ui/widgets/detailView.js @@ -1038,7 +1038,7 @@ ); }; - var replaceTabs = function($detailView, $newTabs, tabs, options) { + var replaceTabs = function($detailView, tabs, options) { var $detailViewElems = $detailView.find('ul.ui-tabs-nav, .detail-group'); $detailView.tabs('destroy'); $detailViewElems.remove(); @@ -1057,25 +1057,32 @@ ); }; - $.fn.detailView = function(args) { + $.fn.detailView = function(args, options) { var $detailView = this; + + if (options == 'refresh') { + var $tabs = replaceTabs($detailView, args.tabs, { + context: args.context, + tabFilter: args.tabFilter + }); + } else { + $detailView.addClass('detail-view'); + $detailView.data('view-args', args); - $detailView.addClass('detail-view'); - $detailView.data('view-args', args); + if (args.$listViewRow) { + $detailView.data('list-view-row', args.$listViewRow); + } - if (args.$listViewRow) { - $detailView.data('list-view-row', args.$listViewRow); + // Create toolbar + var $toolbar = makeToolbar().appendTo($detailView); + + // Create tabs + var $tabs = makeTabs($detailView, args.tabs, { + context: args.context, + tabFilter: args.tabFilter + }).appendTo($detailView); } - // Create toolbar - var $toolbar = makeToolbar().appendTo($detailView); - - // Create tabs - var $tabs = makeTabs($detailView, args.tabs, { - context: args.context, - tabFilter: args.tabFilter - }).appendTo($detailView); - $detailView.tabs(); return $detailView; @@ -1154,4 +1161,17 @@ return true; }); + + // Detail view refresh handler + $(window).bind('cloudStack.detailsRefresh', function() { + var $detailView = $('.detail-view'); + + $detailView.each(function() { + var $detailView = $(this), + args = $detailView.data('view-args'); + + $detailView.detailView(args, 'refresh'); + }); + }); + }(window.jQuery, window.cloudStack, window._l)); From 2a95258fe986cd5a84c33b250a976f73480d8113 Mon Sep 17 00:00:00 2001 From: Wido den Hollander Date: Fri, 27 Jul 2012 18:06:38 +0200 Subject: [PATCH 09/11] setup: Add database upgrade for 3.0.3 to 4.0 Also added a upgrade path from 3.X.X to 4.0, this should work. --- .../cloud/upgrade/DatabaseUpgradeChecker.java | 13 ++-- .../com/cloud/upgrade/dao/Upgrade303to40.java | 67 +++++++++++++++++++ 2 files changed, 75 insertions(+), 5 deletions(-) create mode 100644 server/src/com/cloud/upgrade/dao/Upgrade303to40.java diff --git a/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java b/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java index 88577ea89ab..eb7a11c63e6 100755 --- a/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java +++ b/server/src/com/cloud/upgrade/DatabaseUpgradeChecker.java @@ -55,6 +55,7 @@ import com.cloud.upgrade.dao.Upgrade229to2210; import com.cloud.upgrade.dao.Upgrade301to302; import com.cloud.upgrade.dao.Upgrade302to303; import com.cloud.upgrade.dao.Upgrade30to301; +import com.cloud.upgrade.dao.Upgrade303to40; import com.cloud.upgrade.dao.UpgradeSnapshot217to224; import com.cloud.upgrade.dao.UpgradeSnapshot223to224; import com.cloud.upgrade.dao.VersionDao; @@ -152,11 +153,13 @@ public class DatabaseUpgradeChecker implements SystemIntegrityChecker { _upgradeMap.put("2.2.14", new DbUpgrade[] { new Upgrade2214to30(), new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303() }); - _upgradeMap.put("3.0.0", new DbUpgrade[] { new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303() }); - - _upgradeMap.put("3.0.1", new DbUpgrade[] { new Upgrade301to302(), new Upgrade302to303() }); - - _upgradeMap.put("3.0.2", new DbUpgrade[] { new Upgrade302to303() }); + _upgradeMap.put("3.0.0", new DbUpgrade[] { new Upgrade30to301(), new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to40() }); + + _upgradeMap.put("3.0.1", new DbUpgrade[] { new Upgrade301to302(), new Upgrade302to303(), new Upgrade303to40() }); + + _upgradeMap.put("3.0.2", new DbUpgrade[] { new Upgrade302to303(), new Upgrade303to40() }); + + _upgradeMap.put("3.0.3", new DbUpgrade[] { new Upgrade303to40() }); } protected void runScript(Connection conn, File file) { diff --git a/server/src/com/cloud/upgrade/dao/Upgrade303to40.java b/server/src/com/cloud/upgrade/dao/Upgrade303to40.java new file mode 100644 index 00000000000..864d58dc4a6 --- /dev/null +++ b/server/src/com/cloud/upgrade/dao/Upgrade303to40.java @@ -0,0 +1,67 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package com.cloud.upgrade.dao; + +/** + * @author Alena Prokharchyk + */ +import java.io.File; +import java.sql.Connection; + +import org.apache.log4j.Logger; +// +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + +public class Upgrade303to40 implements DbUpgrade { + final static Logger s_logger = Logger.getLogger(Upgrade303to40.class); + + @Override + public String[] getUpgradableVersionRange() { + return new String[] { "3.0.3", "4.0.0" }; + } + + @Override + public String getUpgradedVersion() { + return "4.0.0"; + } + + @Override + public boolean supportsRollingUpgrade() { + return false; + } + + @Override + public File[] getPrepareScripts() { + String script = Script.findScript("", "db/schema-303to40.sql"); + if (script == null) { + throw new CloudRuntimeException("Unable to find db/schema-303to40.sql"); + } + + return new File[] { new File(script) }; + } + + @Override + public void performDataMigration(Connection conn) { + } + + @Override + public File[] getCleanupScripts() { + return null; + } +} From 468f2720eb3897a98ed33b5194218c4b89a8e7db Mon Sep 17 00:00:00 2001 From: kishan Date: Thu, 28 Jun 2012 18:06:30 -0700 Subject: [PATCH 10/11] bug CS-15389: Added prepareStop to Virtualmachine manager and moved network usage collection into prepareStop of VR manager --- .../agent/manager/MockVmManagerImpl.java | 4 +- .../cloud/resource/AgentRoutingResource.java | 4 +- .../computing/FakeComputingResource.java | 11 +- .../computing/LibvirtComputingResource.java | 25 +--- api/src/com/cloud/agent/api/RebootAnswer.java | 33 +---- api/src/com/cloud/agent/api/StopAnswer.java | 8 +- api/src/com/cloud/agent/api/StopCommand.java | 10 -- .../cloud/ovm/hypervisor/OvmResourceBase.java | 10 +- .../vmware/resource/VmwareResource.java | 40 ++---- .../xen/resource/CitrixResourceBase.java | 44 ++---- .../lb/ElasticLoadBalancerManagerImpl.java | 5 + .../baremetal/BareMetalResourceBase.java | 6 +- .../AgentBasedConsoleProxyManager.java | 4 + .../consoleproxy/ConsoleProxyManagerImpl.java | 4 + .../VirtualNetworkApplianceManagerImpl.java | 126 ++++++++++++++---- .../SecondaryStorageManagerImpl.java | 5 + .../src/com/cloud/vm/UserVmManagerImpl.java | 3 + .../src/com/cloud/vm/VirtualMachineGuru.java | 7 + .../cloud/vm/VirtualMachineManagerImpl.java | 9 +- 19 files changed, 183 insertions(+), 175 deletions(-) diff --git a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java b/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java index dca44c46716..5e66464e66b 100644 --- a/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java +++ b/agent-simulator/src/com/cloud/agent/manager/MockVmManagerImpl.java @@ -352,12 +352,12 @@ public class MockVmManagerImpl implements MockVmManager { _mockAgentMgr.handleSystemVMStop(vm.getId()); } - return new StopAnswer(cmd, null, new Integer(0), new Long(100), new Long(200)); + return new StopAnswer(cmd, null, new Integer(0), true); } @Override public Answer rebootVM(RebootCommand cmd) { - return new RebootAnswer(cmd, "Rebooted "+cmd.getVmName()); + return new RebootAnswer(cmd, "Rebooted "+cmd.getVmName(), false); } @Override diff --git a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java b/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java index e259c39f3a7..291e46a0bed 100644 --- a/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java +++ b/agent-simulator/src/com/cloud/resource/AgentRoutingResource.java @@ -233,10 +233,10 @@ public class AgentRoutingResource extends AgentStorageResource { Answer result = _simMgr.simulate(cmd, hostGuid); if (!result.getResult()) { - return new StopAnswer(cmd, result.getDetails()); + return new StopAnswer(cmd, result.getDetails(), false); } - answer = new StopAnswer(cmd, null, 0, new Long(100), new Long(200)); + answer = new StopAnswer(cmd, null, 0, true); Pair data = _runningVms.get(vmName); if (data != null) { this.usedCpu -= data.first(); diff --git a/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java b/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java index d9b5d949c44..abfa4787a51 100644 --- a/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/FakeComputingResource.java @@ -443,8 +443,6 @@ public class FakeComputingResource extends ServerResourceBase implements String vmName = cmd.getVmName(); Integer port = vmMgr.getVncPort(vmName); - Long bytesReceived = null; - Long bytesSent = null; State state = null; synchronized (_vms) { @@ -462,17 +460,16 @@ public class FakeComputingResource extends ServerResourceBase implements s_logger.warn("Couldn't stop " + vmName); if (result != null) { - return new StopAnswer(cmd, result); + return new StopAnswer(cmd, result, false); } } - answer = new StopAnswer(cmd, null, port, bytesSent, bytesReceived); + answer = new StopAnswer(cmd, null, port, true); String result2 = vmMgr.cleanupVnet(cmd.getVnet()); if (result2 != null) { result = result2 + (result != null ? ("\n" + result) : ""); - answer = new StopAnswer(cmd, result, port, bytesSent, - bytesReceived); + answer = new StopAnswer(cmd, result, port, true); } _dhcpSnooper.cleanup(vmName, null); @@ -498,7 +495,7 @@ public class FakeComputingResource extends ServerResourceBase implements protected Answer execute(RebootCommand cmd) { VmMgr vmMgr = getVmManager(); vmMgr.rebootVM(cmd.getVmName()); - return new RebootAnswer(cmd, "success", 0L, 0L); + return new RebootAnswer(cmd, "success", true); } private Answer execute(PingTestCommand cmd) { diff --git a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java index 347ff87ac9d..a4854bec394 100755 --- a/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java +++ b/agent/src/com/cloud/agent/resource/computing/LibvirtComputingResource.java @@ -2270,8 +2270,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements } private Answer execute(RebootCommand cmd) { - Long bytesReceived = null; - Long bytesSent = null; synchronized (_vms) { _vms.put(cmd.getVmName(), State.Starting); @@ -2288,13 +2286,12 @@ public class LibvirtComputingResource extends ServerResourceBase implements } get_rule_logs_for_vms(); - return new RebootAnswer(cmd, null, bytesSent, bytesReceived, - vncPort); + return new RebootAnswer(cmd, null, vncPort); } else { - return new RebootAnswer(cmd, result); + return new RebootAnswer(cmd, result, false); } } catch (LibvirtException e) { - return new RebootAnswer(cmd, e.getMessage()); + return new RebootAnswer(cmd, e.getMessage(), false); } finally { synchronized (_vms) { _vms.put(cmd.getVmName(), State.Running); @@ -2303,16 +2300,7 @@ public class LibvirtComputingResource extends ServerResourceBase implements } protected Answer execute(RebootRouterCommand cmd) { - Long bytesSent = 0L; - Long bytesRcvd = 0L; - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - long[] stats = getNetworkStats(cmd.getPrivateIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd); - answer.setBytesSent(bytesSent); - answer.setBytesReceived(bytesRcvd); String result = _virtRouterResource.connect(cmd.getPrivateIpAddress()); if (result == null) { networkUsage(cmd.getPrivateIpAddress(), "create", null); @@ -2345,9 +2333,6 @@ public class LibvirtComputingResource extends ServerResourceBase implements protected Answer execute(StopCommand cmd) { final String vmName = cmd.getVmName(); - Long bytesReceived = new Long(0); - Long bytesSent = new Long(0); - State state = null; synchronized (_vms) { state = _vms.get(vmName); @@ -2373,9 +2358,9 @@ public class LibvirtComputingResource extends ServerResourceBase implements result = result2 + result; } state = State.Stopped; - return new StopAnswer(cmd, result, 0, bytesSent, bytesReceived); + return new StopAnswer(cmd, result, 0, true); } catch (LibvirtException e) { - return new StopAnswer(cmd, e.getMessage()); + return new StopAnswer(cmd, e.getMessage(), false); } finally { synchronized (_vms) { if (state != null) { diff --git a/api/src/com/cloud/agent/api/RebootAnswer.java b/api/src/com/cloud/agent/api/RebootAnswer.java index b69afb22bbd..da53b4fb1a3 100644 --- a/api/src/com/cloud/agent/api/RebootAnswer.java +++ b/api/src/com/cloud/agent/api/RebootAnswer.java @@ -17,52 +17,25 @@ package com.cloud.agent.api; public class RebootAnswer extends Answer { - Long bytesSent; - Long bytesReceived; Integer vncPort; protected RebootAnswer() { } - public RebootAnswer(RebootCommand cmd, String details, Long bytesSent, Long bytesReceived, Integer vncport) { + public RebootAnswer(RebootCommand cmd, String details, Integer vncport) { super(cmd, true, details); - this.bytesReceived = bytesReceived; - this.bytesSent = bytesSent; this.vncPort = vncport; } - public RebootAnswer(RebootCommand cmd, String details, Long bytesSent, Long bytesReceived) { - super(cmd, true, details); - this.bytesReceived = bytesReceived; - this.bytesSent = bytesSent; + public RebootAnswer(RebootCommand cmd, String details, boolean success) { + super(cmd, success, details); this.vncPort = null; } - public RebootAnswer(RebootCommand cmd, String details) { - super(cmd, false, details); - bytesSent = null; - bytesReceived = null; - } - public RebootAnswer(RebootCommand cmd, Exception e) { super(cmd, e); } - public void setBytesReceived(Long bytesReceived) { - this.bytesReceived = bytesReceived; - } - - public Long getBytesReceived() { - return bytesReceived; - } - - public void setBytesSent(Long bytesSent) { - this.bytesSent = bytesSent; - } - - public Long getBytesSent() { - return bytesSent; - } public Integer getVncPort() { return vncPort; } diff --git a/api/src/com/cloud/agent/api/StopAnswer.java b/api/src/com/cloud/agent/api/StopAnswer.java index 4050cd37d03..52f28f165f2 100755 --- a/api/src/com/cloud/agent/api/StopAnswer.java +++ b/api/src/com/cloud/agent/api/StopAnswer.java @@ -22,13 +22,13 @@ public class StopAnswer extends RebootAnswer { protected StopAnswer() { } - public StopAnswer(StopCommand cmd, String details, Integer vncPort, Long bytesSent, Long bytesReceived) { - super(cmd, details, bytesSent, bytesReceived); + public StopAnswer(StopCommand cmd, String details, Integer vncPort, boolean success) { + super(cmd, details, success); this.vncPort = vncPort; } - public StopAnswer(StopCommand cmd, String details) { - super(cmd, details); + public StopAnswer(StopCommand cmd, String details, boolean success) { + super(cmd, details, success); vncPort = null; } diff --git a/api/src/com/cloud/agent/api/StopCommand.java b/api/src/com/cloud/agent/api/StopCommand.java index 734da8415ec..176a7fb86ee 100755 --- a/api/src/com/cloud/agent/api/StopCommand.java +++ b/api/src/com/cloud/agent/api/StopCommand.java @@ -23,7 +23,6 @@ public class StopCommand extends RebootCommand { private boolean isProxy=false; private String urlPort=null; private String publicConsoleProxyIpAddress=null; - private String privateRouterIpAddress=null; protected StopCommand() { } @@ -45,12 +44,6 @@ public class StopCommand extends RebootCommand { this.vnet = vnet; } - public StopCommand(VirtualMachine vm, String vmName, String vnet, String privateRouterIpAddress) { - super(vmName); - this.vnet = vnet; - this.privateRouterIpAddress = privateRouterIpAddress; - } - public StopCommand(String vmName) { super(vmName); } @@ -76,7 +69,4 @@ public class StopCommand extends RebootCommand { return this.publicConsoleProxyIpAddress; } - public String getPrivateRouterIpAddress() { - return privateRouterIpAddress; - } } diff --git a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java index c48b13f66bb..c5cb586e528 100755 --- a/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java +++ b/plugins/hypervisors/ovm/src/com/cloud/ovm/hypervisor/OvmResourceBase.java @@ -716,7 +716,7 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { vm = OvmVm.getDetails(_conn, vmName); } catch (XmlRpcException e) { s_logger.debug("Unable to get details of vm: " + vmName + ", treating it as stopped", e); - return new StopAnswer(cmd, "success", 0, 0L, 0L); + return new StopAnswer(cmd, "success", 0, true); } deleteAllNetworkRulesForVm(vmName); @@ -724,10 +724,10 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { cleanup(vm); state = State.Stopped; - return new StopAnswer(cmd, "success", 0, 0L, 0L); + return new StopAnswer(cmd, "success", 0, true); } catch (Exception e) { s_logger.debug("Stop " + vmName + "failed", e); - return new StopAnswer(cmd, e.getMessage()); + return new StopAnswer(cmd, e.getMessage(), false); } finally { synchronized(_vms) { if (state != null) { @@ -749,10 +749,10 @@ public class OvmResourceBase implements ServerResource, HypervisorResource { try { Map res = OvmVm.reboot(_conn, vmName); Integer vncPort = Integer.parseInt(res.get("vncPort")); - return new RebootAnswer(cmd, null, null, null, vncPort); + return new RebootAnswer(cmd, null, vncPort); } catch (Exception e) { s_logger.debug("Reboot " + vmName + " failed", e); - return new RebootAnswer(cmd, e.getMessage()); + return new RebootAnswer(cmd, e.getMessage(), false); } finally { synchronized(_vms) { _vms.put(cmd.getVmName(), State.Running); diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 208cbbea8ce..e837dbd15e8 100755 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -2027,16 +2027,6 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.setCustomFieldValue(CustomFieldConstants.CLOUD_NIC_MASK, "0"); if (getVmState(vmMo) != State.Stopped) { - Long bytesSent = 0L; - Long bytesRcvd = 0L; - - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - if (cmd.getPrivateRouterIpAddress() != null) { - long[] stats = getNetworkStats(cmd.getPrivateRouterIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } - } // before we stop VM, remove all possible snapshots on the VM to let // disk chain be collapsed @@ -2044,11 +2034,11 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa vmMo.removeAllSnapshots(); if (vmMo.safePowerOff(_shutdown_waitMs)) { state = State.Stopped; - return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", 0, bytesSent, bytesRcvd); + return new StopAnswer(cmd, "Stop VM " + cmd.getVmName() + " Succeed", 0, true); } else { String msg = "Have problem in powering off VM " + cmd.getVmName() + ", let the process continue"; s_logger.warn(msg); - return new StopAnswer(cmd, msg, 0, 0L, 0L); + return new StopAnswer(cmd, msg, 0, true); } } else { state = State.Stopped; @@ -2056,7 +2046,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "VM " + cmd.getVmName() + " is already in stopped state"; s_logger.info(msg); - return new StopAnswer(cmd, msg, 0, 0L, 0L); + return new StopAnswer(cmd, msg, 0, true); } finally { synchronized (_vms) { _vms.put(cmd.getVmName(), state); @@ -2069,7 +2059,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "VM " + cmd.getVmName() + " is no longer in vSphere"; s_logger.info(msg); - return new StopAnswer(cmd, msg, 0, 0L, 0L); + return new StopAnswer(cmd, msg, 0, true); } } catch (Exception e) { if (e instanceof RemoteException) { @@ -2079,7 +2069,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "StopCommand failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } } @@ -2088,17 +2078,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa s_logger.info("Executing resource RebootRouterCommand: " + _gson.toJson(cmd)); } - Long bytesSent = 0L; - Long bytesRcvd = 0L; - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - long[] stats = getNetworkStats(cmd.getPrivateIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } - RebootAnswer answer = (RebootAnswer) execute((RebootCommand) cmd); - answer.setBytesSent(bytesSent); - answer.setBytesReceived(bytesRcvd); if (answer.getResult()) { String connectResult = connect(cmd.getVmName(), cmd.getPrivateIpAddress()); @@ -2124,7 +2104,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (vmMo != null) { try { vmMo.rebootGuest(); - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } catch(ToolsUnavailable e) { s_logger.warn("VMware tools is not installed at guest OS, we will perform hard reset for reboot"); } catch(Exception e) { @@ -2133,16 +2113,16 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // continue to try with hard-reset if (vmMo.reset()) { - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } String msg = "Reboot failed in vSphere. vm: " + cmd.getVmName(); s_logger.warn(msg); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } else { String msg = "Unable to find the VM in vSphere to reboot. vm: " + cmd.getVmName(); s_logger.warn(msg); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } } catch (Exception e) { if (e instanceof RemoteException) { @@ -2152,7 +2132,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa String msg = "RebootCommand failed due to " + VmwareHelper.getExceptionMessage(e); s_logger.error(msg); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index c81d4613509..19cb7961819 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -201,7 +201,6 @@ import com.cloud.utils.net.NetUtils; import com.cloud.vm.DiskProfile; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.VirtualMachineName; import com.trilead.ssh2.SCPClient; import com.xensource.xenapi.Bond; import com.xensource.xenapi.Connection; @@ -2823,10 +2822,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe vms = VM.getByNameLabel(conn, cmd.getVmName()); } catch (XenAPIException e0) { s_logger.debug("getByNameLabel failed " + e0.toString()); - return new RebootAnswer(cmd, "getByNameLabel failed " + e0.toString()); + return new RebootAnswer(cmd, "getByNameLabel failed " + e0.toString(), false); } catch (Exception e0) { s_logger.debug("getByNameLabel failed " + e0.getMessage()); - return new RebootAnswer(cmd, "getByNameLabel failed"); + return new RebootAnswer(cmd, "getByNameLabel failed", false); } for (VM vm : vms) { try { @@ -2834,10 +2833,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (Exception e) { String msg = e.toString(); s_logger.warn(msg, e); - return new RebootAnswer(cmd, msg); + return new RebootAnswer(cmd, msg, false); } } - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } finally { synchronized (_cluster.intern()) { s_vms.put(_cluster, _name, cmd.getVmName(), State.Running); @@ -2848,16 +2847,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe protected Answer execute(RebootRouterCommand cmd) { Connection conn = getConnection(); - Long bytesSent = 0L; - Long bytesRcvd = 0L; - if (VirtualMachineName.isValidRouterName(cmd.getVmName())) { - long[] stats = getNetworkStats(conn, cmd.getPrivateIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } RebootAnswer answer = execute((RebootCommand) cmd); - answer.setBytesSent(bytesSent); - answer.setBytesReceived(bytesRcvd); if (answer.getResult()) { String cnct = connect(conn, cmd.getVmName(), cmd.getPrivateIpAddress()); networkUsage(conn, cmd.getPrivateIpAddress(), "create", null); @@ -3320,23 +3310,21 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe s_logger.info("VM does not exist on XenServer" + _host.uuid); s_vms.remove(_cluster, _name, vmName); } - return new StopAnswer(cmd, "VM does not exist", 0 , 0L, 0L); + return new StopAnswer(cmd, "VM does not exist", 0 , true); } - Long bytesSent = 0L; - Long bytesRcvd = 0L; for (VM vm : vms) { VM.Record vmr = vm.getRecord(conn); if (vmr.isControlDomain) { String msg = "Tring to Shutdown control domain"; s_logger.warn(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } if (vmr.powerState == VmPowerState.RUNNING && !isRefNull(vmr.residentOn) && !vmr.residentOn.getUuid(conn).equals(_host.uuid)) { String msg = "Stop Vm " + vmName + " failed due to this vm is not running on this host: " + _host.uuid + " but host:" + vmr.residentOn.getUuid(conn); s_logger.warn(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } State state = s_vms.getState(_cluster, vmName); @@ -3350,13 +3338,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe if (vmr.powerState == VmPowerState.RUNNING) { /* when stop a vm, set affinity to current xenserver */ vm.setAffinity(conn, vm.getResidentOn(conn)); - if (VirtualMachineName.isValidRouterName(vmName)) { - if (cmd.getPrivateRouterIpAddress() != null) { - long[] stats = getNetworkStats(conn, cmd.getPrivateRouterIpAddress()); - bytesSent = stats[0]; - bytesRcvd = stats[1]; - } - } + if (_canBridgeFirewall) { String result = callHostPlugin(conn, "vmops", "destroy_network_rules_for_vm", "vmName", cmd .getVmName()); @@ -3371,7 +3353,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (Exception e) { String msg = "Catch exception " + e.getClass().getName() + " when stop VM:" + cmd.getVmName() + " due to " + e.toString(); s_logger.debug(msg); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } finally { try { @@ -3396,7 +3378,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe disableVlanNetwork(conn, network); } } - return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, bytesSent, bytesRcvd); + return new StopAnswer(cmd, "Stop VM " + vmName + " Succeed", 0, true); } } catch (XenAPIException e) { String msg = "VM destroy failed in Stop " + vmName + " Command due to " + e.toString(); @@ -3416,16 +3398,16 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe } catch (XenAPIException e) { String msg = "Stop Vm " + vmName + " fail due to " + e.toString(); s_logger.warn(msg, e); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } catch (XmlRpcException e) { String msg = "Stop Vm " + vmName + " fail due to " + e.getMessage(); s_logger.warn(msg, e); - return new StopAnswer(cmd, msg); + return new StopAnswer(cmd, msg, false); } catch (Exception e) { s_logger.warn("Unable to stop " + vmName + " due to ", e); return new StopAnswer(cmd, e); } - return new StopAnswer(cmd, "Stop VM failed"); + return new StopAnswer(cmd, "Stop VM failed", false); } private List getVdis(Connection conn, VM vm) { diff --git a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java index 8d1963d303a..272c3575d1f 100644 --- a/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java +++ b/plugins/network-elements/elastic-loadbalancer/src/com/cloud/network/lb/ElasticLoadBalancerManagerImpl.java @@ -996,4 +996,9 @@ public class ElasticLoadBalancerManagerImpl implements // TODO Auto-generated method stub return false; } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } + } diff --git a/server/src/com/cloud/baremetal/BareMetalResourceBase.java b/server/src/com/cloud/baremetal/BareMetalResourceBase.java index 4835bd4efb6..24f80026bbf 100755 --- a/server/src/com/cloud/baremetal/BareMetalResourceBase.java +++ b/server/src/com/cloud/baremetal/BareMetalResourceBase.java @@ -428,10 +428,10 @@ public class BareMetalResourceBase implements ServerResource { protected RebootAnswer execute(final RebootCommand cmd) { if (!doScript(_rebootCommand)) { - return new RebootAnswer(cmd, "IPMI reboot failed"); + return new RebootAnswer(cmd, "IPMI reboot failed", false); } - return new RebootAnswer(cmd, "reboot succeeded", null, null); + return new RebootAnswer(cmd, "reboot succeeded", true); } protected StopAnswer execute(final StopCommand cmd) { @@ -466,7 +466,7 @@ public class BareMetalResourceBase implements ServerResource { count++; } - return success ? new StopAnswer(cmd, "Success", null, Long.valueOf(0), Long.valueOf(0)) : new StopAnswer(cmd, "IPMI power off failed"); + return success ? new StopAnswer(cmd, "Success", null, true) : new StopAnswer(cmd, "IPMI power off failed", false); } protected StartAnswer execute(StartCommand cmd) { diff --git a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java index 6d20fb2fc31..a7e457c02d4 100755 --- a/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java +++ b/server/src/com/cloud/consoleproxy/AgentBasedConsoleProxyManager.java @@ -353,4 +353,8 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu // TODO Auto-generated method stub return false; } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } } diff --git a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java index ec4f685f3a7..71013751234 100755 --- a/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java +++ b/server/src/com/cloud/consoleproxy/ConsoleProxyManagerImpl.java @@ -2014,4 +2014,8 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx // TODO Auto-generated method stub return false; } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 766c7690ee8..82f7231e172 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -506,34 +506,13 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian txn.start(); final UserStatisticsVO userStats = _userStatsDao.lock(router.getAccountId(), router.getDataCenterIdToDeployIn(), router.getNetworkId(), null, router.getId(), router.getType().toString()); if (userStats != null) { - final RebootAnswer sa = (RebootAnswer) answer; - final Long received = sa.getBytesReceived(); - long netBytes = 0; - if (received != null) { - if (received.longValue() >= userStats.getCurrentBytesReceived()) { - netBytes = received.longValue(); - } else { - netBytes = userStats.getCurrentBytesReceived() + received; - } - } else { - netBytes = userStats.getCurrentBytesReceived(); - } + final long currentBytesRcvd = userStats.getCurrentBytesReceived(); userStats.setCurrentBytesReceived(0); - userStats.setNetBytesReceived(userStats.getNetBytesReceived() + netBytes); + userStats.setNetBytesReceived(userStats.getNetBytesReceived() + currentBytesRcvd); - final Long sent = sa.getBytesSent(); - - if (sent != null) { - if (sent.longValue() >= userStats.getCurrentBytesSent()) { - netBytes = sent.longValue(); - } else { - netBytes = userStats.getCurrentBytesSent() + sent; - } - } else { - netBytes = userStats.getCurrentBytesSent(); - } - userStats.setNetBytesSent(userStats.getNetBytesSent() + netBytes); + final long currentBytesSent = userStats.getCurrentBytesSent(); userStats.setCurrentBytesSent(0); + userStats.setNetBytesSent(userStats.getNetBytesSent() + currentBytesSent); _userStatsDao.update(userStats.getId(), userStats); s_logger.debug("Successfully updated user statistics as a part of domR " + router + " reboot/stop"); } else { @@ -542,7 +521,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian txn.commit(); } catch (final Exception e) { txn.rollback(); - throw new CloudRuntimeException("Problem getting stats after reboot/stop ", e); + throw new CloudRuntimeException("Problem updating stats after reboot/stop ", e); } } @@ -2985,4 +2964,99 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian return false; } + + @Override + public void prepareStop(VirtualMachineProfile profile){ + //Collect network usage before stopping Vm + VMInstanceVO vm = profile.getVirtualMachine(); + DomainRouterVO router = _routerDao.findById(vm.getId()); + if(router == null){ + return; + } + /*String privateIP = router.getPrivateIpAddress(); + + if (privateIP != null) { + List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); + + for (Long guestNtwkId : routerGuestNtwkIds) { + boolean forVpc = router.getVpcId() != null; + Network guestNtwk = _networkMgr.getNetwork(guestNtwkId); + Nic guestNic = _nicDao.findByInstanceIdAndNetworkId(guestNtwk.getId(), router.getId()); + NicProfile guestNicProfile = new NicProfile(guestNic, guestNtwk, guestNic.getBroadcastUri(), + guestNic.getIsolationUri(), _networkMgr.getNetworkRate(guestNtwk.getId(), router.getId()), + _networkMgr.isSecurityGroupSupportedInNetwork(guestNtwk), + _networkMgr.getNetworkTag(router.getHypervisorType(), guestNtwk)); + final NetworkUsageCommand usageCmd = new NetworkUsageCommand(privateIP, router.getHostName(), + forVpc, _itMgr.toNicTO(guestNicProfile, router.getHypervisorType())); + UserStatisticsVO previousStats = _statsDao.findBy(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + NetworkUsageAnswer answer = null; + try { + answer = (NetworkUsageAnswer) _agentMgr.easySend(router.getHostId(), usageCmd); + } catch (Exception e) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId(), e); + continue; + } + + if (answer != null) { + if (!answer.getResult()) { + s_logger.warn("Error while collecting network stats from router: "+router.getInstanceName()+" from host: "+router.getHostId() + "; details: " + answer.getDetails()); + continue; + } + Transaction txn = Transaction.open(Transaction.CLOUD_DB); + try { + if ((answer.getBytesReceived() == 0) && (answer.getBytesSent() == 0)) { + s_logger.debug("Recieved and Sent bytes are both 0. Not updating user_statistics"); + continue; + } + txn.start(); + UserStatisticsVO stats = _statsDao.lock(router.getAccountId(), + router.getDataCenterIdToDeployIn(), guestNtwkId, null, router.getId(), router.getType().toString()); + if (stats == null) { + s_logger.warn("unable to find stats for account: " + router.getAccountId()); + continue; + } + + if(previousStats != null + && ((previousStats.getCurrentBytesReceived() != stats.getCurrentBytesReceived()) + || (previousStats.getCurrentBytesSent() != stats.getCurrentBytesSent()))){ + s_logger.debug("Router stats changed from the time NetworkUsageCommand was sent. " + + "Ignoring current answer. Router: "+answer.getRouterName()+" Rcvd: " + + answer.getBytesReceived()+ "Sent: " +answer.getBytesSent()); + continue; + } + + if (stats.getCurrentBytesReceived() > answer.getBytesReceived()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesReceived() + + " Stored: " + stats.getCurrentBytesReceived()); + } + stats.setNetBytesReceived(stats.getNetBytesReceived() + stats.getCurrentBytesReceived()); + } + stats.setCurrentBytesReceived(answer.getBytesReceived()); + if (stats.getCurrentBytesSent() > answer.getBytesSent()) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Received # of bytes that's less than the last one. " + + "Assuming something went wrong and persisting it. Router: " + + answer.getRouterName()+" Reported: " + answer.getBytesSent() + + " Stored: " + stats.getCurrentBytesSent()); + } + stats.setNetBytesSent(stats.getNetBytesSent() + stats.getCurrentBytesSent()); + } + stats.setCurrentBytesSent(answer.getBytesSent()); + _statsDao.update(stats.getId(), stats); + txn.commit(); + } catch (Exception e) { + txn.rollback(); + s_logger.warn("Unable to update user statistics for account: " + router.getAccountId() + + " Rx: " + answer.getBytesReceived() + "; Tx: " + answer.getBytesSent()); + } finally { + txn.close(); + } + } + } + }*/ + } } diff --git a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java index 1121bb19f61..3ef055d74c0 100755 --- a/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java +++ b/server/src/com/cloud/storage/secondary/SecondaryStorageManagerImpl.java @@ -1457,5 +1457,10 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V Commands cmds, ReservationContext context) { // TODO Auto-generated method stub return false; + } + + @Override + public void prepareStop(VirtualMachineProfile profile) { + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 649e215acf0..b221ef1eac9 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -3630,5 +3630,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return vm; } + @Override + public void prepareStop(VirtualMachineProfile profile) { + } } diff --git a/server/src/com/cloud/vm/VirtualMachineGuru.java b/server/src/com/cloud/vm/VirtualMachineGuru.java index b92982c7b31..26c3944394c 100644 --- a/server/src/com/cloud/vm/VirtualMachineGuru.java +++ b/server/src/com/cloud/vm/VirtualMachineGuru.java @@ -74,4 +74,11 @@ public interface VirtualMachineGuru { * @return id if the handler works for this vm and can parse id. null if not. */ Long convertToId(String vmName); + + /** + * Prepare Vm for Stop + * @param profile + * @return + */ + void prepareStop(VirtualMachineProfile profile); } diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index ac8fd2ab46b..3f7cab914a9 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1070,11 +1070,10 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene if (vm.getState() != State.Stopping) { throw new CloudRuntimeException("We cannot proceed with stop VM " + vm + " since it is not in 'Stopping' state, current state: " + vm.getState()); } - String routerPrivateIp = null; - if (vm.getType() == VirtualMachine.Type.DomainRouter) { - routerPrivateIp = vm.getPrivateIpAddress(); - } - StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null, routerPrivateIp); + + vmGuru.prepareStop(profile); + + StopCommand stop = new StopCommand(vm, vm.getInstanceName(), null); boolean stopped = false; StopAnswer answer = null; try { From dabd85e153e2a46e243cba4b06dd13c5674a84b5 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Fri, 27 Jul 2012 15:07:36 -0700 Subject: [PATCH 11/11] CS-15717: fail to delete the network when corresponding network elements fail to be destroyed --- server/src/com/cloud/network/NetworkManagerImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index c96ea52b299..83acc9b9c35 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -3215,7 +3215,10 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag s_logger.debug("Sending destroy to " + element); } - element.destroy(network); + if (!element.destroy(network)) { + success = false; + s_logger.warn("Unable to complete destroy of the network: failed to destroy network element " + element.getName()); + } } catch (ResourceUnavailableException e) { s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e); success = false; @@ -3225,7 +3228,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag } catch (Exception e) { s_logger.warn("Unable to complete destroy of the network due to element: " + element.getName(), e); success = false; - } + } } }