mirror of https://github.com/apache/cloudstack.git
bug 8962: added usage related and resource count related code, changed the API name as suggested. Incorporated relevant review comments
This commit is contained in:
parent
932e3c3a65
commit
abb37acbdd
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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<VMInstanceVO> vmOldProfile = new VirtualMachineProfileImpl<VMInstanceVO>(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<VolumeVO> 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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue