From 2bdaaa48a6ae56f3468b3ec84dbd66a3aa44a4fd Mon Sep 17 00:00:00 2001 From: abhishek Date: Thu, 26 Aug 2010 13:37:57 -0700 Subject: [PATCH] Refactored the destroy vm command --- .../com/cloud/api/commands/DestroyVMCmd.java | 111 ++++---- server/src/com/cloud/vm/UserVmManager.java | 4 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 244 ++++++++++-------- 3 files changed, 192 insertions(+), 167 deletions(-) diff --git a/server/src/com/cloud/api/commands/DestroyVMCmd.java b/server/src/com/cloud/api/commands/DestroyVMCmd.java index 2e286ab06bb..2bdec2113fc 100644 --- a/server/src/com/cloud/api/commands/DestroyVMCmd.java +++ b/server/src/com/cloud/api/commands/DestroyVMCmd.java @@ -18,30 +18,18 @@ package com.cloud.api.commands; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - import org.apache.log4j.Logger; -import com.cloud.api.BaseCmd; +import com.cloud.api.BaseAsyncCmd; +import com.cloud.api.Implementation; import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; -import com.cloud.user.Account; -import com.cloud.utils.Pair; -import com.cloud.vm.UserVmVO; - -public class DestroyVMCmd extends BaseCmd { +import com.cloud.api.BaseCmd.Manager; + +@Implementation(method="destroyVm", manager=Manager.UserVmManager) +public class DestroyVMCmd extends BaseAsyncCmd { public static final Logger s_logger = Logger.getLogger(DestroyVMCmd.class.getName()); private static final String s_name = "destroyvirtualmachineresponse"; - private static final List> s_properties = new ArrayList>(); - - static { - s_properties.add(new Pair(BaseCmd.Properties.ID, Boolean.TRUE)); - s_properties.add(new Pair(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE)); - s_properties.add(new Pair(BaseCmd.Properties.USER_ID, Boolean.FALSE)); - } ///////////////////////////////////////////////////// //////////////// API parameters ///////////////////// @@ -68,48 +56,51 @@ public class DestroyVMCmd extends BaseCmd { return s_name; } - public List> getProperties() { - return s_properties; - } - - @Override - public List> execute(Map params) { - Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName()); - Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName()); - Long vmId = (Long)params.get(BaseCmd.Properties.ID.getName()); +// @Override +// public List> execute(Map params) { +// Account account = (Account)params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName()); +// Long userId = (Long)params.get(BaseCmd.Properties.USER_ID.getName()); +// Long vmId = (Long)params.get(BaseCmd.Properties.ID.getName()); +// +// // Verify input parameters +// UserVmVO vmInstance = getManagementServer().findUserVMInstanceById(vmId.longValue()); +// if (vmInstance == null) { +// throw new ServerApiException (BaseCmd.VM_INVALID_PARAM_ERROR, "unable to find a virtual machine with id " + vmId); +// } +// +// if (account != null) { +// if (!isAdmin(account.getType())) { +// if (account.getId().longValue() != vmInstance.getAccountId()) { +// throw new ServerApiException(BaseCmd.VM_INVALID_PARAM_ERROR, "unable to find a virtual machine with id " + vmId + "for this account"); +// } +// } else if (!getManagementServer().isChildDomain(account.getDomainId(), vmInstance.getDomainId())) { +// throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to destroy virtual machine with id " + vmId + ", permission denied."); +// } +// } +// +// // If command is executed via 8096 port, set userId to the id of System account (1) +// if (userId == null) { +// userId = Long.valueOf(1); +// } +// +// long jobId = getManagementServer().destroyVirtualMachineAsync(userId.longValue(), vmId.longValue()); +// if (jobId == 0) { +// s_logger.warn("Unable to schedule async-job for DestroyVM command"); +// } else { +// if (s_logger.isDebugEnabled()) +// s_logger.debug("DestroyVM command has been accepted, job id: " + jobId); +// } +// +// List> returnValues = new ArrayList>(); +// returnValues.add(new Pair(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId))); +// +// return returnValues; +// } - // Verify input parameters - UserVmVO vmInstance = getManagementServer().findUserVMInstanceById(vmId.longValue()); - if (vmInstance == null) { - throw new ServerApiException (BaseCmd.VM_INVALID_PARAM_ERROR, "unable to find a virtual machine with id " + vmId); - } - if (account != null) { - if (!isAdmin(account.getType())) { - if (account.getId().longValue() != vmInstance.getAccountId()) { - throw new ServerApiException(BaseCmd.VM_INVALID_PARAM_ERROR, "unable to find a virtual machine with id " + vmId + "for this account"); - } - } else if (!getManagementServer().isChildDomain(account.getDomainId(), vmInstance.getDomainId())) { - throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to destroy virtual machine with id " + vmId + ", permission denied."); - } - } - - // If command is executed via 8096 port, set userId to the id of System account (1) - if (userId == null) { - userId = Long.valueOf(1); - } - - long jobId = getManagementServer().destroyVirtualMachineAsync(userId.longValue(), vmId.longValue()); - if (jobId == 0) { - s_logger.warn("Unable to schedule async-job for DestroyVM command"); - } else { - if (s_logger.isDebugEnabled()) - s_logger.debug("DestroyVM command has been accepted, job id: " + jobId); - } - - List> returnValues = new ArrayList>(); - returnValues.add(new Pair(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId))); - - return returnValues; - } + @Override + public String getResponse() { + // TODO Auto-generated method stub + return null; + } } diff --git a/server/src/com/cloud/vm/UserVmManager.java b/server/src/com/cloud/vm/UserVmManager.java index 6dfd19c1656..82b94a1ef8c 100644 --- a/server/src/com/cloud/vm/UserVmManager.java +++ b/server/src/com/cloud/vm/UserVmManager.java @@ -23,6 +23,7 @@ import java.util.List; import com.cloud.agent.api.VmStatsEntry; import com.cloud.api.ServerApiException; import com.cloud.api.commands.CreateTemplateCmd; +import com.cloud.api.commands.DestroyVMCmd; import com.cloud.api.commands.DetachVolumeCmd; import com.cloud.api.commands.RebootVMCmd; import com.cloud.api.commands.RecoverVMCmd; @@ -102,8 +103,9 @@ public interface UserVmManager extends Manager, VirtualMachineManager * @param userId the id of the user performing the action * @param vmId the id of the virtual machine. */ + boolean destroyVm(DestroyVMCmd cmd); boolean destroyVirtualMachine(long userId, long vmId); - OperationResponse executeDestroyVM(DestroyVMExecutor executor, VMOperationParam param); +// OperationResponse executeDestroyVM(DestroyVMExecutor executor, VMOperationParam param); /** diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index b8ad9164c01..23dd6d16f4a 100644 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -65,6 +65,7 @@ import com.cloud.alert.AlertManager; import com.cloud.api.BaseCmd; import com.cloud.api.ServerApiException; import com.cloud.api.commands.CreateTemplateCmd; +import com.cloud.api.commands.DestroyVMCmd; import com.cloud.api.commands.DetachVolumeCmd; import com.cloud.api.commands.RebootVMCmd; import com.cloud.api.commands.RecoverVMCmd; @@ -1789,112 +1790,112 @@ public class UserVmManagerImpl implements UserVmManager { return true; } - @Override @DB - public OperationResponse executeDestroyVM(DestroyVMExecutor executor, VMOperationParam param) { - UserVmVO vm = _vmDao.findById(param.getVmId()); - State state = vm.getState(); - OperationResponse response; - String resultDescription = "Success"; - - if (vm == null || state == State.Destroyed || state == State.Expunging || vm.getRemoved() != null) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("Unable to find vm or vm is destroyed: " + param.getVmId()); - } - resultDescription = "VM does not exist or already in destroyed state"; - response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_FAILED, 0, resultDescription); - return response; - } - - if(state == State.Stopping) { - if (s_logger.isDebugEnabled()) { - s_logger.debug("VM is being stopped: " + param.getVmId()); - } - resultDescription = "VM is being stopped, please re-try later"; - response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_FAILED, 0, resultDescription); - return response; - } - - if (state == State.Running) { - if (vm.getHostId() == null) { - resultDescription = "VM host is null (invalid VM)"; - response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_FAILED, 0, resultDescription); - if(s_logger.isDebugEnabled()) - s_logger.debug("Execute asynchronize destroy VM command: " + resultDescription); - return response; - } - - if (!_vmDao.updateIf(vm, Event.StopRequested, vm.getHostId())) { - resultDescription = "Failed to issue stop command, please re-try later"; - response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_FAILED, 0, resultDescription); - if(s_logger.isDebugEnabled()) - s_logger.debug("Execute asynchronize destroy VM command:" + resultDescription); - return response; - } - long childEventId = EventUtils.saveStartedEvent(param.getUserId(), param.getAccountId(), - EventTypes.EVENT_VM_STOP, "stopping vm " + vm.getName(), 0); - param.setChildEventId(childEventId); - StopCommand cmd = new StopCommand(vm, vm.getInstanceName(), vm.getVnet()); - try { - long seq = _agentMgr.send(vm.getHostId(), new Command[] {cmd}, true, - new VMOperationListener(executor, param, vm, 0)); - resultDescription = "Execute asynchronize destroy VM command: sending stop command to agent, seq - " + seq; - if(s_logger.isDebugEnabled()) - s_logger.debug(resultDescription); - response = new OperationResponse(OperationResponse.STATUS_IN_PROGRESS, resultDescription); - return response; - } catch (AgentUnavailableException e) { - resultDescription = "Agent is not available"; - response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_FAILED, 0, resultDescription); - return response; - } - } - - Transaction txn = Transaction.currentTxn(); - txn.start(); - - _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); - if (!_vmDao.updateIf(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId()) ) { - resultDescription = "Unable to destroy the vm because it is not in the correct state"; - s_logger.debug(resultDescription + vm.toString()); - - txn.rollback(); - response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_FAILED, 0, resultDescription); - return response; - } - - // Now that the VM is destroyed, clean the network rules associated with it. - cleanNetworkRules(param.getUserId(), vm.getId()); - - // Mark the VM's root disk as destroyed - List volumes = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT); - for (VolumeVO volume : volumes) { - _storageMgr.destroyVolume(volume); - } - - // Mark the VM's data disks as detached - volumes = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.DATADISK); - for (VolumeVO volume : volumes) { - _volsDao.detachVolume(volume.getId()); - } - - txn.commit(); - response = new OperationResponse(OperationResponse.STATUS_SUCCEEDED, resultDescription); - executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), - AsyncJobResult.STATUS_SUCCEEDED, 0, "success"); - return response; - } +// @Override @DB +// public OperationResponse executeDestroyVM(DestroyVMExecutor executor, VMOperationParam param) { +// UserVmVO vm = _vmDao.findById(param.getVmId()); +// State state = vm.getState(); +// OperationResponse response; +// String resultDescription = "Success"; +// +// if (vm == null || state == State.Destroyed || state == State.Expunging || vm.getRemoved() != null) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("Unable to find vm or vm is destroyed: " + param.getVmId()); +// } +// resultDescription = "VM does not exist or already in destroyed state"; +// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_FAILED, 0, resultDescription); +// return response; +// } +// +// if(state == State.Stopping) { +// if (s_logger.isDebugEnabled()) { +// s_logger.debug("VM is being stopped: " + param.getVmId()); +// } +// resultDescription = "VM is being stopped, please re-try later"; +// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_FAILED, 0, resultDescription); +// return response; +// } +// +// if (state == State.Running) { +// if (vm.getHostId() == null) { +// resultDescription = "VM host is null (invalid VM)"; +// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_FAILED, 0, resultDescription); +// if(s_logger.isDebugEnabled()) +// s_logger.debug("Execute asynchronize destroy VM command: " + resultDescription); +// return response; +// } +// +// if (!_vmDao.updateIf(vm, Event.StopRequested, vm.getHostId())) { +// resultDescription = "Failed to issue stop command, please re-try later"; +// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_FAILED, 0, resultDescription); +// if(s_logger.isDebugEnabled()) +// s_logger.debug("Execute asynchronize destroy VM command:" + resultDescription); +// return response; +// } +// long childEventId = EventUtils.saveStartedEvent(param.getUserId(), param.getAccountId(), +// EventTypes.EVENT_VM_STOP, "stopping vm " + vm.getName(), 0); +// param.setChildEventId(childEventId); +// StopCommand cmd = new StopCommand(vm, vm.getInstanceName(), vm.getVnet()); +// try { +// long seq = _agentMgr.send(vm.getHostId(), new Command[] {cmd}, true, +// new VMOperationListener(executor, param, vm, 0)); +// resultDescription = "Execute asynchronize destroy VM command: sending stop command to agent, seq - " + seq; +// if(s_logger.isDebugEnabled()) +// s_logger.debug(resultDescription); +// response = new OperationResponse(OperationResponse.STATUS_IN_PROGRESS, resultDescription); +// return response; +// } catch (AgentUnavailableException e) { +// resultDescription = "Agent is not available"; +// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_FAILED, 0, resultDescription); +// return response; +// } +// } +// +// Transaction txn = Transaction.currentTxn(); +// txn.start(); +// +// _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); +// if (!_vmDao.updateIf(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId()) ) { +// resultDescription = "Unable to destroy the vm because it is not in the correct state"; +// s_logger.debug(resultDescription + vm.toString()); +// +// txn.rollback(); +// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_FAILED, 0, resultDescription); +// return response; +// } +// +// // Now that the VM is destroyed, clean the network rules associated with it. +// cleanNetworkRules(param.getUserId(), vm.getId()); +// +// // Mark the VM's root disk as destroyed +// List volumes = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT); +// for (VolumeVO volume : volumes) { +// _storageMgr.destroyVolume(volume); +// } +// +// // Mark the VM's data disks as detached +// volumes = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.DATADISK); +// for (VolumeVO volume : volumes) { +// _volsDao.detachVolume(volume.getId()); +// } +// +// txn.commit(); +// response = new OperationResponse(OperationResponse.STATUS_SUCCEEDED, resultDescription); +// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(), +// AsyncJobResult.STATUS_SUCCEEDED, 0, "success"); +// return response; +// } @Override @DB public boolean recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, InternalErrorException { @@ -3413,6 +3414,37 @@ public class UserVmManagerImpl implements UserVmManager { return status; } } + + @Override + public boolean destroyVm(DestroyVMCmd cmd) { + + Account account = (Account)UserContext.current().getAccountObject(); + Long userId = UserContext.current().getUserId(); + Long vmId = cmd.getId(); + + //Verify input parameters + UserVmVO vmInstance = _vmDao.findById(vmId.longValue()); + if (vmInstance == null) { + throw new ServerApiException(BaseCmd.VM_INVALID_PARAM_ERROR, "unable to find a virtual machine with id " + vmId); + } + + userId = accountAndUserValidation(vmId, account, userId, vmInstance); + + EventUtils.saveScheduledEvent(userId, vmInstance.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Destroying Vm with Id: "+vmId); + + boolean status = destroyVirtualMachine(userId, vmId); + + if(status) + { + EventUtils.saveEvent(userId, vmInstance.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Successfully destroyed vm with id:"+vmId); + return status; + } + else + { + EventUtils.saveEvent(userId, vmInstance.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Failed to destroy vm with id:"+vmId); + return status; + } + } }