}
DataCenterVO zone = _dcDao.findById(vm.getDataCenterId());
// Get serviceOffering and Volumes for Virtual Machine
ServiceOfferingVO offering = _serviceOfferingDao.findByIdIncludingRemoved(vm.getServiceOfferingId());
List<VolumeVO> volumes = _volsDao.findByInstance(cmd.getVmId());
//Remove vm from instance group
removeInstanceFromInstanceGroup(cmd.getVmId());
// VV 2: check if account/domain is with in resource limits to create a new vm
resourceLimitCheck(newAccount, new Long(offering.getCpu()), new Long(offering.getRamSize()));
// VV 3: check if volumes and primary storage space are with in resource limits
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.volume,
_volsDao.findByInstance(cmd.getVmId()).size());
Long totalVolumesSize = (long) 0;
for (VolumeVO volume : volumes) {
totalVolumesSize += volume.getSize();
}
_resourceLimitMgr.checkResourceLimit(newAccount, ResourceType.primary_storage, totalVolumesSize);
// VV 4: Check if new owner can use the vm template
VirtualMachineTemplate template = _templateDao.findById(vm
.getTemplateId());
if (!template.isPublicTemplate()) {
Account templateOwner = _accountMgr.getAccount(template
.getAccountId());
_accountMgr.checkAccess(newAccount, null, true, templateOwner);
}
// VV 5: check the new account can create vm in the domain
DomainVO domain = _domainDao.findById(cmd.getDomainId());
_accountMgr.checkAccess(newAccount, domain);
Transaction txn = Transaction.currentTxn();
txn.start();
//generate destroy vm event for usage
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
VirtualMachine.class.getName(), vm.getUuid());
// update resource counts for old account
resourceCountDecrement(oldAccount.getAccountId(), new Long(offering.getCpu()),
new Long(offering.getRamSize()));
// OWNERSHIP STEP 1: update the vm owner
vm.setAccountId(newAccount.getAccountId());
vm.setDomainId(cmd.getDomainId());
_vmDao.persist(vm);
// OS 2: update volume
for (VolumeVO volume : volumes) {
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_DELETE, volume.getAccountId(),
volume.getDataCenterId(), volume.getId(), volume.getName(), Volume.class.getName(), volume.getUuid());
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.volume);
_resourceLimitMgr.decrementResourceCount(oldAccount.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
volume.setAccountId(newAccount.getAccountId());
volume.setDomainId(newAccount.getDomainId());
_volsDao.persist(volume);
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.volume);
_resourceLimitMgr.incrementResourceCount(newAccount.getAccountId(), ResourceType.primary_storage,
new Long(volume.getSize()));
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VOLUME_CREATE, volume.getAccountId(),
volume.getDataCenterId(), volume.getId(), volume.getName(),
volume.getDiskOfferingId(), volume.getTemplateId(), volume.getSize(), Volume.class.getName(),
volume.getUuid());
//snapshots: mark these removed in db
List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdIncludingRemoved(volume.getId());
for (SnapshotVO snapshot: snapshots){
_snapshotDao.remove(snapshot.getId());
}
}
//update resource count of new account
resourceCountIncrement(newAccount.getAccountId(), new Long(offering.getCpu()), new Long(offering.getRamSize()));
//generate usage events to account for this change
UsageEventUtils.publishUsageEvent(EventTypes.EVENT_VM_CREATE, vm.getAccountId(), vm.getDataCenterId(), vm.getId(),
vm.getHostName(), vm.getServiceOfferingId(), vm.getTemplateId(), vm.getHypervisorType().toString(),
VirtualMachine.class.getName(), vm.getUuid());