diff --git a/api/src/com/cloud/api/commands/MoveUserVMCmd.java b/api/src/com/cloud/api/commands/MoveUserVMCmd.java deleted file mode 100644 index d9d7f971832..00000000000 --- a/api/src/com/cloud/api/commands/MoveUserVMCmd.java +++ /dev/null @@ -1,109 +0,0 @@ -/** - * Copyright (C) 2010 Cloud.com, Inc. All rights reserved. - * - * This software is licensed under the GNU General Public License v3 or later. - * - * It is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ -package com.cloud.api.commands; - - -import org.apache.log4j.Logger; - -import com.cloud.api.ApiConstants; -import com.cloud.api.BaseAsyncCmd; -import com.cloud.api.BaseCmd; -import com.cloud.api.Implementation; -import com.cloud.api.Parameter; -import com.cloud.api.ServerApiException; -import com.cloud.api.response.UserVmResponse; -import com.cloud.api.response.ZoneResponse; -import com.cloud.async.AsyncJob; -import com.cloud.event.EventTypes; -import com.cloud.user.Account; -import com.cloud.uservm.UserVm; - -@Implementation(description="Move a user VM to another user under same domain.", responseObject=UserVmResponse.class) -public class MoveUserVMCmd extends BaseAsyncCmd { - public static final Logger s_logger = Logger.getLogger(MoveUserVMCmd.class.getName()); - - private static final String s_name = "moveuservmresponse"; - - ///////////////////////////////////////////////////// - //////////////// API parameters ///////////////////// - ///////////////////////////////////////////////////// - - @Parameter(name=ApiConstants.VIRTUAL_MACHINE_ID, type=CommandType.LONG, required=true, description="the vm ID of the user VM to be moved") - private Long virtualMachineId; - - @Parameter(name=ApiConstants.ACCOUNT_ID, type=CommandType.LONG,required=true, description="the accopunt id of the new owner account") - private Long accountId; - - - ///////////////////////////////////////////////////// - /////////////////// Accessors /////////////////////// - ///////////////////////////////////////////////////// - - public Long getVmId() { - return virtualMachineId; - } - - public Long getAccountId() { - return accountId; - } - ///////////////////////////////////////////////////// - /////////////// API Implementation/////////////////// - ///////////////////////////////////////////////////// - - @Override - public String getCommandName() { - return s_name; - } - - @Override - public void execute(){ - try { - UserVm userVm = _userVmService.moveVMToUser(this); - if (userVm == null){ - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to move vm"); - } - UserVmResponse response = _responseGenerator.createUserVmResponse("virtualmachine", userVm).get(0); - response.setResponseName(DeployVMCmd.getResultObjectName()); - this.setResponseObject(response); - }catch (Exception e){ - e.printStackTrace(); - throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to move vm " + e.getMessage()); - } - - } - - @Override - public long getEntityOwnerId() { - UserVm vm = _responseGenerator.findUserVmById(getVmId()); - if (vm != null) { - return vm.getAccountId(); - } - - return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked - } - - @Override - public String getEventDescription() { - return "moving user vm: " + getVmId(); - } - - @Override - public String getEventType() { - return EventTypes.EVENT_VM_MOVE; - } -} diff --git a/api/src/com/cloud/vm/UserVmService.java b/api/src/com/cloud/vm/UserVmService.java index b6b37e681d8..1cf2d3a012e 100755 --- a/api/src/com/cloud/vm/UserVmService.java +++ b/api/src/com/cloud/vm/UserVmService.java @@ -22,6 +22,7 @@ import java.util.Map; import javax.naming.InsufficientResourcesException; +import com.cloud.api.commands.AssignVMCmd; import com.cloud.api.commands.AttachVolumeCmd; import com.cloud.api.commands.CreateTemplateCmd; import com.cloud.api.commands.CreateVMGroupCmd; @@ -30,7 +31,6 @@ import com.cloud.api.commands.DeployVMCmd; import com.cloud.api.commands.DestroyVMCmd; import com.cloud.api.commands.DetachVolumeCmd; import com.cloud.api.commands.ListVMsCmd; -import com.cloud.api.commands.MoveUserVMCmd; import com.cloud.api.commands.RebootVMCmd; import com.cloud.api.commands.RecoverVMCmd; import com.cloud.api.commands.ResetVMPasswordCmd; @@ -378,7 +378,7 @@ public interface UserVmService { */ VirtualMachine migrateVirtualMachine(Long vmId, Host destinationHost) throws ResourceUnavailableException, ConcurrentOperationException, ManagementServerException, VirtualMachineMigrationException; - UserVm moveVMToUser(MoveUserVMCmd moveUserVMCmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException ; + UserVm moveVMToUser(AssignVMCmd moveUserVMCmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException ; VirtualMachine vmStorageMigration(Long vmId, StoragePool destPool); diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 86d1bd0eda0..b66ed506bd0 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -48,7 +48,7 @@ recoverVirtualMachine=com.cloud.api.commands.RecoverVMCmd;7 listVirtualMachines=com.cloud.api.commands.ListVMsCmd;15 getVMPassword=com.cloud.api.commands.GetVMPasswordCmd;15 migrateVirtualMachine=com.cloud.api.commands.MigrateVMCmd;1 -moveVirtualMachine=com.cloud.api.commands.MoveUserVMCmd;15 +assignVirtualMachine=com.cloud.api.commands.AssignVMCmd;15 restoreVm=com.cloud.api.commands.RestoreVMCmd;15 #### snapshot commands diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index ecc4cd95d9c..ad4b516a548 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -63,7 +63,7 @@ import com.cloud.api.commands.DeployVMCmd; import com.cloud.api.commands.DestroyVMCmd; import com.cloud.api.commands.DetachVolumeCmd; import com.cloud.api.commands.ListVMsCmd; -import com.cloud.api.commands.MoveUserVMCmd; +import com.cloud.api.commands.AssignVMCmd; import com.cloud.api.commands.RebootVMCmd; import com.cloud.api.commands.RecoverVMCmd; import com.cloud.api.commands.ResetVMPasswordCmd; @@ -3290,17 +3290,17 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager return migratedVm; } - + @DB @Override @ActionEvent(eventType = EventTypes.EVENT_VM_MOVE, eventDescription = "move VM to another user", async = false) - public UserVm moveVMToUser(MoveUserVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { + public UserVm moveVMToUser(AssignVMCmd cmd) throws ResourceAllocationException, ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { // VERIFICATIONS and VALIDATIONS //VV 1: verify the two users Account oldAccount = UserContext.current().getCaller(); Account newAccount = _accountService.getAccount(cmd.getAccountId()); if (newAccount == null || newAccount.getType() == Account.ACCOUNT_TYPE_PROJECT) { - throw new InvalidParameterValueException("Unable to find account " + newAccount + " in domain " + oldAccount.getDomainId()); + throw new InvalidParameterValueException("Invalid accountid=" + cmd.getAccountId() + " in domain " + oldAccount.getDomainId()); } //don't allow to move the vm from the project @@ -3314,8 +3314,9 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager //get the VM UserVmVO vm = _vmDao.findById(cmd.getVmId()); - // VV 3: check if vm is running - if (vm.getState() == State.Running) { + if (vm == null){ + throw new InvalidParameterValueException("There is no vm by that id " + cmd.getVmId()); + } else if (vm.getState() == State.Running) { // VV 3: check if vm is running if (s_logger.isDebugEnabled()) { s_logger.debug("VM is Running, unable to move the vm " + vm); } @@ -3334,21 +3335,41 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager _accountMgr.checkAccess(newAccount, domain); DataCenterVO zone = _dcDao.findById(vm.getDataCenterIdToDeployIn()); + + //check is zone networking is advanced + if (zone.getNetworkType() != NetworkType.Advanced) { + throw new InvalidParameterValueException("Assing virtual machine to another account is only available for advanced networking " + vm); + } + VMInstanceVO vmoi = _itMgr.findByIdAndType(vm.getType(), vm.getId()); VirtualMachineProfileImpl vmOldProfile = new VirtualMachineProfileImpl(vmoi); - + Transaction txn = Transaction.currentTxn(); + txn.start(); + //generate destory vm event for usage + _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), + vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString())); + // update resource counts + _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm); + // OWNERSHIP STEP 1: update the vm owner vm.setAccountId(newAccount.getAccountId()); - vm.setAccountId(newAccount.getId()); _vmDao.persist(vm); - // OS 2: update volume List volumes = _volsDao.findByInstance(cmd.getVmId()); for (VolumeVO volume : volumes) { volume.setAccountId(cmd.getAccountId()); + _resourceLimitMgr.decrementResourceCount(vm.getAccountId(), ResourceType.volume, new Long(volumes.size())); _volsDao.persist(volume); + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.volume, new Long(volumes.size())); } + + _resourceLimitMgr.incrementResourceCount(vm.getAccountId(), ResourceType.user_vm); + //generate usage evenst to account for this change + _usageEventDao.persist(new UsageEventVO(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterIdToDeployIn(), vm.getId(), + vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString())); + + // OS 3: update the network if (zone.getNetworkType() == NetworkType.Advanced) { @@ -3404,6 +3425,8 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager } } + txn.commit(); + return vm; }