fix CLOUDSTACK-2157 On VMWare ESXi host deployment: Expunged VMs are not getting cleaned up from the host
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/79cc241c Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/79cc241c Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/79cc241c Branch: refs/heads/marvin_refactor Commit: 79cc241c64df1451ce2413b206f6723e3e58de18 Parents: 96837ed Author: Mice Xia <mice_...@tcloudcomputing.com> Authored: Thu Apr 25 14:23:36 2013 +0800 Committer: Mice Xia <mice_...@tcloudcomputing.com> Committed: Thu Apr 25 14:25:03 2013 +0800 ---------------------------------------------------------------------- .../com/cloud/agent/api/UnregisterVMCommand.java | 34 ++++++++++++ api/src/com/cloud/hypervisor/HypervisorGuru.java | 9 +++ .../src/com/cloud/hypervisor/guru/VMwareGuru.java | 9 +++ .../hypervisor/vmware/resource/VmwareResource.java | 40 +++++++++++++++ .../com/cloud/hypervisor/HypervisorGuruBase.java | 5 ++ server/src/com/cloud/vm/UserVmManagerImpl.java | 1 + .../com/cloud/vm/VirtualMachineManagerImpl.java | 24 +++++++++ 7 files changed, 122 insertions(+), 0 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/api/src/com/cloud/agent/api/UnregisterVMCommand.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/agent/api/UnregisterVMCommand.java b/api/src/com/cloud/agent/api/UnregisterVMCommand.java new file mode 100644 index 0000000..428ffea --- /dev/null +++ b/api/src/com/cloud/agent/api/UnregisterVMCommand.java @@ -0,0 +1,34 @@ +// 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.agent.api; + +public class UnregisterVMCommand extends Command { + String vmName; + + public UnregisterVMCommand(String vmName){ + this.vmName = vmName; + } + + @Override + public boolean executeInSequence() { + return false; + } + + public String getVmName() { + return vmName; + } +} http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/api/src/com/cloud/hypervisor/HypervisorGuru.java ---------------------------------------------------------------------- diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java index b4a0b06..eab4e4e 100644 --- a/api/src/com/cloud/hypervisor/HypervisorGuru.java +++ b/api/src/com/cloud/hypervisor/HypervisorGuru.java @@ -16,6 +16,8 @@ // under the License. package com.cloud.hypervisor; +import java.util.List; + import com.cloud.agent.api.Command; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; @@ -57,4 +59,11 @@ public interface HypervisorGuru extends Adapter { * @return */ NicTO toNicTO(NicProfile profile); + + /** + * Give hypervisor guru opportunity to decide if certain command needs to be done after expunge VM from DB + * @param vm + * @return a list of Commands + */ + List<Command> finalizeExpunge(VirtualMachine vm); } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java ---------------------------------------------------------------------- diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java index 122ba3b..ee1b324 100644 --- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java +++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/guru/VMwareGuru.java @@ -36,6 +36,7 @@ import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; +import com.cloud.agent.api.UnregisterVMCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.to.NicTO; @@ -353,4 +354,12 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru { return tokens[0] + "@" + vCenterIp; } + + @Override + public List<Command> finalizeExpunge(VirtualMachine vm) { + UnregisterVMCommand unregisterVMCommand = new UnregisterVMCommand(vm.getInstanceName()); + List<Command> commands = new ArrayList<Command>(); + commands.add(unregisterVMCommand); + return commands; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java ---------------------------------------------------------------------- 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 3dc23cc..dbcb318 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 @@ -73,6 +73,7 @@ import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.DeleteStoragePoolCommand; import com.cloud.agent.api.DeleteVMSnapshotAnswer; import com.cloud.agent.api.DeleteVMSnapshotCommand; +import com.cloud.agent.api.UnregisterVMCommand; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetHostStatsAnswer; @@ -473,6 +474,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa answer = execute((CheckS2SVpnConnectionsCommand) cmd); } else if (clz == ResizeVolumeCommand.class) { return execute((ResizeVolumeCommand) cmd); + } else if (clz == UnregisterVMCommand.class) { + return execute((UnregisterVMCommand) cmd); } else { answer = Answer.createUnsupportedCommandAnswer(cmd); } @@ -3689,6 +3692,43 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } + protected Answer execute(UnregisterVMCommand cmd){ + if (s_logger.isInfoEnabled()) { + s_logger.info("Executing resource UnregisterVMCommand: " + _gson.toJson(cmd)); + } + + VmwareContext context = getServiceContext(); + VmwareHypervisorHost hyperHost = getHyperHost(context); + try { + VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName()); + if (vmMo != null) { + try { + context.getService().unregisterVM(vmMo.getMor()); + return new Answer(cmd, true, "unregister succeeded"); + } catch(Exception e) { + s_logger.warn("We are not able to unregister VM " + VmwareHelper.getExceptionMessage(e)); + } + + String msg = "Expunge failed in vSphere. vm: " + cmd.getVmName(); + s_logger.warn(msg); + return new Answer(cmd, false, msg); + } else { + String msg = "Unable to find the VM in vSphere to unregister, assume it is already removed. VM: " + cmd.getVmName(); + s_logger.warn(msg); + return new Answer(cmd, true, msg); + } + } catch (Exception e) { + if (e instanceof RemoteException) { + s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context"); + invalidateServiceContext(); + } + + String msg = "UnregisterVMCommand failed due to " + VmwareHelper.getExceptionMessage(e); + s_logger.error(msg); + return new Answer(cmd, false, msg); + } + } + @Override public Answer execute(DestroyCommand cmd) { if (s_logger.isInfoEnabled()) { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/server/src/com/cloud/hypervisor/HypervisorGuruBase.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index d77796d..ca1644a 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -129,4 +129,9 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis public long getCommandHostDelegation(long hostId, Command cmd) { return hostId; } + + @Override + public List<Command> finalizeExpunge(VirtualMachine vm) { + return null; + } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/server/src/com/cloud/vm/UserVmManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index f24288a..ebc5757 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -1554,6 +1554,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Use } } finally { scanLock.releaseRef(); + UserContext.unregisterContext(); } } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/79cc241c/server/src/com/cloud/vm/VirtualMachineManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index c1f3f15..252fc99 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -434,6 +435,29 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac //remove the overcommit detials from the uservm details _uservmDetailsDao.deleteDetails(vm.getId()); + // send hypervisor-dependent commands before removing + HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType()); + List<Command> finalizeExpungeCommands = hvGuru.finalizeExpunge(vm); + if(finalizeExpungeCommands != null && finalizeExpungeCommands.size() > 0){ + Long hostId = vm.getHostId() != null ? vm.getHostId() : vm.getLastHostId(); + if(hostId != null){ + Commands cmds = new Commands(OnError.Stop); + for (Command command : finalizeExpungeCommands) { + cmds.addCommand(command); + } + _agentMgr.send(hostId, cmds); + if(!cmds.isSuccessful()){ + for (Answer answer : cmds.getAnswers()){ + if(answer != null && !answer.getResult()){ + s_logger.warn("Failed to expunge vm due to: " + answer.getDetails()); + break; + } + } + return false; + } + } + } + if (s_logger.isDebugEnabled()) { s_logger.debug("Expunged " + vm); }