use of com.cloud.legacymodel.exceptions.ResourceAllocationException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method recoverVirtualMachine.
@Override
@DB
public UserVm recoverVirtualMachine(final RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException {
final Long vmId = cmd.getId();
final Account caller = CallContext.current().getCallingAccount();
final Long userId = caller.getAccountId();
// Verify input parameters
final UserVmVO vm = _vmDao.findById(vmId);
if (vm == null) {
throw new InvalidParameterValueException("unable to find a virtual machine with id " + vmId);
}
// When trying to expunge, permission is denied when the caller is not an admin and the AllowUserExpungeRecoverVm is false for the caller.
if (!_accountMgr.isAdmin(userId) && !AllowUserExpungeRecoverVm.valueIn(userId)) {
throw new PermissionDeniedException("Recovering a vm can only be done by an Admin. Or when the allow.user.expunge.recover.vm key is set.");
}
if (vm.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find vm or vm is removed: " + vmId);
}
throw new InvalidParameterValueException("Unable to find vm by id " + vmId);
}
if (vm.getState() != State.Destroyed) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("vm is not in the right state: " + vmId);
}
throw new InvalidParameterValueException("Vm with id " + vmId + " is not in the right state");
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Recovering vm " + vmId);
}
Transaction.execute(new TransactionCallbackWithExceptionNoReturn<ResourceAllocationException>() {
@Override
public void doInTransactionWithoutResult(final TransactionStatus status) throws ResourceAllocationException {
final Account account = _accountDao.lockRow(vm.getAccountId(), true);
// if the account is deleted, throw error
if (account.getRemoved() != null) {
throw new CloudRuntimeException("Unable to recover VM as the account is deleted");
}
// Get serviceOffering for Virtual Machine
final ServiceOfferingVO serviceOffering = _serviceOfferingDao.findById(vm.getId(), vm.getServiceOfferingId());
// First check that the maximum number of UserVMs, CPU and Memory limit for the given
// accountId will not be exceeded
resourceLimitCheck(account, vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
_haMgr.cancelDestroy(vm, vm.getHostId());
try {
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.RecoveryRequested, null)) {
s_logger.debug("Unable to recover the vm because it is not in the correct state: " + vmId);
throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
}
} catch (final NoTransitionException e) {
throw new InvalidParameterValueException("Unable to recover the vm because it is not in the correct state: " + vmId);
}
// Recover the VM's disks
final List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
for (final VolumeVO volume : volumes) {
if (volume.getVolumeType().equals(VolumeType.ROOT)) {
// Create an event
final Long templateId = volume.getTemplateId();
final Long diskOfferingId = volume.getDiskOfferingId();
Long offeringId = null;
if (diskOfferingId != null) {
final DiskOfferingVO offering = _diskOfferingDao.findById(diskOfferingId);
if (offering != null && offering.getType() == DiskOfferingVO.Type.Disk) {
offeringId = offering.getId();
}
}
}
}
// Update Resource Count for the given account
resourceCountIncrement(account.getId(), vm.isDisplayVm(), new Long(serviceOffering.getCpu()), new Long(serviceOffering.getRamSize()));
}
});
return _vmDao.findById(vmId);
}
use of com.cloud.legacymodel.exceptions.ResourceAllocationException in project cosmic by MissionCriticalCloud.
the class UserVmManagerImpl method createVirtualMachine.
@DB
private UserVm createVirtualMachine(final Zone zone, final ServiceOffering serviceOffering, final VirtualMachineTemplate tmplt, String hostName, final String displayName, final Account owner, final Long diskOfferingId, final Long diskSize, final List<NetworkVO> networkList, final String group, final HTTPMethod httpmethod, final String userData, final String sshKeyPair, final HypervisorType hypervisor, final Account caller, final Map<Long, IpAddresses> requestedIps, final IpAddresses defaultIps, final Boolean isDisplayVm, final String keyboard, final List<Long> affinityGroupIdList, final Map<String, String> customParameters, final String customId, final DiskControllerType diskControllerType, final Long bootMenuTimeout, MaintenancePolicy maintenancePolicy, OptimiseFor optimiseFor, String manufacturerString, String bootOrder) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, StorageUnavailableException, ResourceAllocationException {
_accountMgr.checkAccess(caller, null, true, owner);
if (owner.getState() == Account.State.disabled) {
throw new PermissionDeniedException("The owner of vm to deploy is disabled: " + owner);
}
final VMTemplateVO template = _templateDao.findById(tmplt.getId());
if (template != null) {
_templateDao.loadDetails(template);
}
if (optimiseFor == null) {
if (template.getOptimiseFor() != null) {
optimiseFor = template.getOptimiseFor();
} else {
optimiseFor = OptimiseFor.Generic;
}
}
if (manufacturerString == null) {
manufacturerString = template.getManufacturerString();
}
if (maintenancePolicy == null) {
maintenancePolicy = template.getMaintenancePolicy();
}
Boolean macLarning = template.getMacLearning();
String cpuFlags = template.getCpuFlags();
final long accountId = owner.getId();
assert !(requestedIps != null && (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null)) : "requestedIp list and defaultNetworkIp should never be " + "specified together";
if (AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getId());
}
// check if zone is dedicated
final DedicatedResourceVO dedicatedZone = _dedicatedDao.findByZoneId(zone.getId());
if (dedicatedZone != null) {
final DomainVO domain = _domainDao.findById(dedicatedZone.getDomainId());
if (domain == null) {
throw new CloudRuntimeException("Unable to find the domain " + zone.getDomainId() + " for the zone: " + zone);
}
// check that caller can operate with domain
_configMgr.checkZoneAccess(caller, zone);
// check that vm owner can create vm in the domain
_configMgr.checkZoneAccess(owner, zone);
}
ServiceOfferingVO offering = _serviceOfferingDao.findById(serviceOffering.getId());
// check if account/domain is with in resource limits to create a new vm
final boolean isIso = ImageFormat.ISO == template.getFormat();
long size = 0;
// custom root disk size, resizes base template to larger size
if (customParameters.containsKey("rootdisksize")) {
final Long rootDiskSize = NumbersUtil.parseLong(customParameters.get("rootdisksize"), -1);
if (rootDiskSize <= 0) {
throw new InvalidParameterValueException("Root disk size should be a positive number.");
}
size = rootDiskSize * GB_TO_BYTES;
}
if (diskOfferingId != null) {
final DiskOfferingVO diskOffering = _diskOfferingDao.findById(diskOfferingId);
if (diskOffering != null && diskOffering.isCustomized()) {
if (diskSize == null) {
throw new InvalidParameterValueException("This disk offering requires a custom size specified");
}
final Long customDiskOfferingMaxSize = VolumeOrchestrationService.CustomDiskOfferingMaxSize.value();
final Long customDiskOfferingMinSize = VolumeOrchestrationService.CustomDiskOfferingMinSize.value();
if (diskSize < customDiskOfferingMinSize || diskSize > customDiskOfferingMaxSize) {
throw new InvalidParameterValueException("VM Creation failed. Volume size: " + diskSize + "GB is out of allowed range. Max: " + customDiskOfferingMaxSize + " Min:" + customDiskOfferingMinSize);
}
size += diskSize * GB_TO_BYTES;
}
size += _diskOfferingDao.findById(diskOfferingId).getDiskSize();
}
resourceLimitCheck(owner, isDisplayVm, new Long(offering.getCpu()), new Long(offering.getRamSize()));
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, isIso || diskOfferingId == null ? 1 : 2);
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, size);
// check that the affinity groups exist
if (affinityGroupIdList != null) {
for (final Long affinityGroupId : affinityGroupIdList) {
final AffinityGroupVO ag = _affinityGroupDao.findById(affinityGroupId);
if (ag == null) {
throw new InvalidParameterValueException("Unable to find affinity group " + ag);
} else if (!_affinityGroupService.isAffinityGroupProcessorAvailable(ag.getType())) {
throw new InvalidParameterValueException("Affinity group type is not supported for group: " + ag + " ,type: " + ag.getType() + " , Please try again after removing the affinity group");
} else {
// verify permissions
if (ag.getAclType() == ACLType.Domain) {
_accountMgr.checkAccess(caller, null, false, owner, ag);
// make sure the owner of these entities is same
if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) {
if (!_affinityGroupService.isAffinityGroupAvailableInDomain(ag.getId(), owner.getDomainId())) {
throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's domain");
}
}
} else {
_accountMgr.checkAccess(caller, null, true, owner, ag);
// make sure the owner of these entities is same
if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || _accountMgr.isRootAdmin(caller.getId())) {
if (ag.getDomainId() != owner.getDomainId()) {
throw new PermissionDeniedException("Affinity Group " + ag + " does not belong to the VM's domain");
}
}
}
}
}
}
final HypervisorType hypervisorType;
if (template.getHypervisorType() == null || template.getHypervisorType() == HypervisorType.None) {
if (hypervisor == null || hypervisor == HypervisorType.None) {
throw new InvalidParameterValueException("hypervisor parameter is needed to deploy VM or the hypervisor parameter value passed is invalid");
}
hypervisorType = hypervisor;
} else {
if (hypervisor != null && hypervisor != HypervisorType.None && hypervisor != template.getHypervisorType()) {
throw new InvalidParameterValueException("Hypervisor passed to the deployVm call, is different from the hypervisor type of the template");
}
hypervisorType = template.getHypervisorType();
}
// check if we have available pools for vm deployment
final long availablePools = _storagePoolDao.countPoolsByStatus(StoragePoolStatus.Up);
if (availablePools < 1) {
throw new StorageUnavailableException("There are no available pools in the UP state for vm deployment", -1);
}
if (template.getTemplateType().equals(TemplateType.SYSTEM)) {
throw new InvalidParameterValueException("Unable to use system template " + template.getId() + " to deploy a user vm");
}
final List<VMTemplateZoneVO> listZoneTemplate = _templateZoneDao.listByZoneTemplate(zone.getId(), template.getId());
if (listZoneTemplate == null || listZoneTemplate.isEmpty()) {
throw new InvalidParameterValueException("The template " + template.getId() + " is not available for use");
}
if (isIso && !template.isBootable()) {
throw new InvalidParameterValueException("Installing from ISO requires an ISO that is bootable: " + template.getId());
}
// Check templates permissions
_accountMgr.checkAccess(owner, AccessType.UseEntry, false, template);
// check if the user data is correct
validateUserData(userData, httpmethod);
// Find an SSH public key corresponding to the key pair name, if one is
// given
String sshPublicKey = null;
if (sshKeyPair != null && !sshKeyPair.equals("")) {
final SSHKeyPair pair = _sshKeyPairDao.findByName(owner.getAccountId(), owner.getDomainId(), sshKeyPair);
if (pair == null) {
throw new InvalidParameterValueException("A key pair with name '" + sshKeyPair + "' was not found.");
}
sshPublicKey = pair.getPublicKey();
}
final List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<>();
final LinkedHashMap<String, NicProfile> networkNicMap = new LinkedHashMap<>();
short defaultNetworkNumber = 0;
boolean vpcNetwork = false;
for (final NetworkVO network : networkList) {
if (network.getDataCenterId() != zone.getId()) {
if (!network.isStrechedL2Network()) {
throw new InvalidParameterValueException("Network id=" + network.getId() + " doesn't belong to zone " + zone.getId());
}
final NetworkOffering ntwkOffering = _networkOfferingDao.findById(network.getNetworkOfferingId());
final Long physicalNetworkId = _networkModel.findPhysicalNetworkId(zone.getId(), ntwkOffering.getTags(), ntwkOffering.getTrafficType());
if (physicalNetworkId == null) {
throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" + " streched to the zone, as we could not find a valid physical network");
}
final String provider = _ntwkSrvcDao.getProviderForServiceInNetwork(network.getId(), Service.Connectivity);
if (!_networkModel.isProviderEnabledInPhysicalNetwork(physicalNetworkId, provider)) {
throw new InvalidParameterValueException("Network in which is VM getting deployed could not be" + " streched to the zone, as we could not find a valid physical network");
}
}
// relax the check if the caller is admin account
if (caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
if (!(network.getGuestType() == GuestType.Shared && network.getAclType() == ACLType.Domain) && !(network.getAclType() == ACLType.Account && network.getAccountId() == accountId)) {
throw new InvalidParameterValueException("only shared network or isolated network with the same account_id can be added to vm");
}
}
IpAddresses requestedIpPair = null;
if (requestedIps != null && !requestedIps.isEmpty()) {
requestedIpPair = requestedIps.get(network.getId());
}
if (requestedIpPair == null) {
requestedIpPair = new IpAddresses(null, null);
} else {
_networkModel.checkRequestedIpAddresses(network.getId(), requestedIpPair);
}
NicProfile profile = new NicProfile(requestedIpPair.getIp4Address(), requestedIpPair.getIp6Address(), requestedIpPair.getMacAddress());
if (defaultNetworkNumber == 0) {
defaultNetworkNumber++;
// if user requested specific ip for default network, add it
if (defaultIps.getIp4Address() != null || defaultIps.getIp6Address() != null) {
_networkModel.checkRequestedIpAddresses(network.getId(), defaultIps);
profile = new NicProfile(defaultIps.getIp4Address(), defaultIps.getIp6Address());
} else if (defaultIps.getMacAddress() != null) {
profile = new NicProfile(null, null, defaultIps.getMacAddress());
}
profile.setDefaultNic(true);
if (!_networkModel.areServicesSupportedInNetwork(network.getId(), new Service[] { Service.UserData })) {
if (userData != null && !userData.isEmpty()) {
throw new InvalidParameterValueException("Unable to deploy VM as UserData is provided while deploying the VM, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
}
if (sshPublicKey != null && !sshPublicKey.isEmpty()) {
throw new InvalidParameterValueException("Unable to deploy VM as SSH keypair is provided while deploying the VM, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
}
if (template.getEnablePassword()) {
throw new InvalidParameterValueException("Unable to deploy VM as template " + template.getId() + " is password enabled, but there is no support for " + Network.Service.UserData.getName() + " service in the default network " + network.getId());
}
}
}
networks.add(new Pair<>(network, profile));
networkNicMap.put(network.getUuid(), profile);
}
// gateway for the vm
if (defaultNetworkNumber == 0) {
throw new InvalidParameterValueException("At least 1 default network has to be specified for the vm");
} else if (defaultNetworkNumber > 1) {
throw new InvalidParameterValueException("Only 1 default network per vm is supported");
}
final long id = _vmDao.getNextInSequence(Long.class, "id");
if (hostName != null) {
// Check is hostName is RFC compliant
checkNameForRFCCompliance(hostName);
}
final String instanceName;
final String uuidName = _uuidMgr.generateUuid(UserVm.class, customId);
if (hostName == null) {
// Generate name using uuid and instance.name global config
hostName = generateHostName(uuidName);
}
if (hostName != null) {
// Check is hostName is RFC compliant
checkNameForRFCCompliance(hostName);
}
instanceName = VirtualMachineName.getVmName(id, owner.getId(), _instance);
// Check if VM with instanceName already exists.
final VMInstanceVO vmObj = _vmInstanceDao.findVMByInstanceName(instanceName);
if (vmObj != null && vmObj.getState() != VirtualMachine.State.Expunging) {
throw new InvalidParameterValueException("There already exists a VM by the display name supplied");
}
checkIfHostNameUniqueInNtwkDomain(hostName, networkList);
long userId = CallContext.current().getCallingUserId();
if (CallContext.current().getCallingAccount().getId() != owner.getId()) {
final List<UserVO> userVOs = _userDao.listByAccount(owner.getAccountId());
if (!userVOs.isEmpty()) {
userId = userVOs.get(0).getId();
}
}
final UserVmVO vm = commitUserVm(zone, template, hostName, displayName, owner, diskOfferingId, diskSize, userData, caller, isDisplayVm, keyboard, accountId, userId, offering, isIso, sshPublicKey, networkNicMap, id, instanceName, uuidName, hypervisorType, customParameters, diskControllerType, manufacturerString, optimiseFor, macLarning, cpuFlags, maintenancePolicy, bootMenuTimeout, bootOrder);
// Assign instance to the group
try {
if (group != null) {
final boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group);
if (!addToGroup) {
throw new CloudRuntimeException("Unable to assign Vm to the group " + group);
}
}
} catch (final Exception ex) {
throw new CloudRuntimeException("Unable to assign Vm to the group " + group);
}
if (affinityGroupIdList != null && !affinityGroupIdList.isEmpty()) {
_affinityGroupVMMapDao.updateMap(vm.getId(), affinityGroupIdList);
}
CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
return vm;
}
use of com.cloud.legacymodel.exceptions.ResourceAllocationException in project cosmic by MissionCriticalCloud.
the class VMSnapshotManagerImpl method allocVMSnapshot.
@Override
public VMSnapshot allocVMSnapshot(final Long vmId, String vsDisplayName, final String vsDescription) throws ResourceAllocationException {
final Account caller = getCaller();
// check if VM exists
final UserVmVO userVmVo = _userVMDao.findById(vmId);
if (userVmVo == null) {
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM:" + vmId + " is a system VM or does not exist");
}
if (_snapshotDao.listByInstanceId(vmId, Snapshot.State.BackedUp).size() > 0 && !HypervisorType.KVM.equals(userVmVo.getHypervisorType())) {
throw new InvalidParameterValueException("VM snapshot for this VM is not allowed. This VM has volumes attached which has snapshots, please remove all snapshots " + "before taking VM snapshot");
}
// VM snapshot with memory is not supported for vGPU Vms
if (_serviceOfferingDetailsDao.findDetail(userVmVo.getServiceOfferingId(), GPU.Keys.vgpuType.toString()) != null) {
throw new InvalidParameterValueException("VM snapshot with MEMORY is not supported for vGPU enabled VMs.");
}
// check hypervisor capabilities
if (!_hypervisorCapabilitiesDao.isVmSnapshotEnabled(userVmVo.getHypervisorType(), "default")) {
throw new InvalidParameterValueException("VM snapshot is not enabled for hypervisor type: " + userVmVo.getHypervisorType());
}
// parameter length check
if (vsDisplayName != null && vsDisplayName.length() > 255) {
throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDisplayName should not exceed 255");
}
if (vsDescription != null && vsDescription.length() > 255) {
throw new InvalidParameterValueException("Creating VM snapshot failed due to length of VM snapshot vsDescription should not exceed 255");
}
// VM snapshot display name must be unique for a VM
final String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
final String vmSnapshotName = userVmVo.getInstanceName() + "_VS_" + timeString;
if (vsDisplayName == null) {
vsDisplayName = vmSnapshotName;
}
if (_vmSnapshotDao.findByName(vmId, vsDisplayName) != null) {
throw new InvalidParameterValueException("Creating VM snapshot failed due to VM snapshot with name '" + vsDisplayName + "' already exists");
}
if (userVmVo.getState() != VirtualMachine.State.Running) {
throw new InvalidParameterValueException("You can only take VM snapshots when the VM is in 'Running' state. Try taking a volume snapshot instead.");
}
// check access
_accountMgr.checkAccess(caller, null, true, userVmVo);
// check max snapshot limit for per VM
if (_vmSnapshotDao.findByVm(vmId).size() >= _vmSnapshotMax) {
throw new CloudRuntimeException("Creating vm snapshot failed due to a VM can just have : " + _vmSnapshotMax + " VM snapshots. Please delete old ones");
}
// check if there are active volume snapshots tasks
final List<VolumeVO> listVolumes = _volumeDao.findByInstance(vmId);
for (final VolumeVO volume : listVolumes) {
final List<SnapshotVO> activeSnapshots = _snapshotDao.listByInstanceId(volume.getInstanceId(), Snapshot.State.Creating, Snapshot.State.CreatedOnPrimary, Snapshot.State.BackingUp);
if (activeSnapshots.size() > 0) {
throw new CloudRuntimeException("There is other active volume snapshot tasks on the instance to which the volume is attached, please try again later.");
}
if (userVmVo.getHypervisorType() == HypervisorType.KVM && volume.getFormat() != ImageFormat.QCOW2) {
throw new CloudRuntimeException("We only support create vm snapshots from vm with QCOW2 image");
}
}
// check if there are other active VM snapshot tasks
if (hasActiveVMSnapshotTasks(vmId)) {
throw new CloudRuntimeException("There is other active vm snapshot tasks on the instance, please try again later");
}
try {
final VMSnapshotVO vmSnapshotVo = new VMSnapshotVO(userVmVo.getAccountId(), userVmVo.getDomainId(), vmId, vsDescription, vmSnapshotName, vsDisplayName, userVmVo.getServiceOfferingId(), VMSnapshot.Type.DiskAndMemory, null);
final VMSnapshot vmSnapshot = _vmSnapshotDao.persist(vmSnapshotVo);
if (vmSnapshot == null) {
throw new CloudRuntimeException("Failed to create snapshot for vm: " + vmId);
}
return vmSnapshot;
} catch (final Exception e) {
final String msg = e.getMessage();
s_logger.error("Create vm snapshot record failed for vm: " + vmId + " due to: " + msg);
}
return null;
}
use of com.cloud.legacymodel.exceptions.ResourceAllocationException in project cosmic by MissionCriticalCloud.
the class TemplateManagerImpl method copy.
@Override
@DB
public boolean copy(final long userId, final VMTemplateVO template, final DataStore srcSecStore, final DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
final long tmpltId = template.getId();
final long dstZoneId = dstZone.getId();
// find all eligible image stores for the destination zone
final List<DataStore> dstSecStores = this._dataStoreMgr.getImageStoresByScope(new ZoneScope(dstZoneId));
if (dstSecStores == null || dstSecStores.isEmpty()) {
throw new StorageUnavailableException("Destination zone is not ready, no image store associated", DataCenter.class, dstZone.getId());
}
final AccountVO account = this._accountDao.findById(template.getAccountId());
// find the size of the template to be copied
final TemplateDataStoreVO srcTmpltStore = this._tmplStoreDao.findByStoreTemplate(srcSecStore.getId(), tmpltId);
this._resourceLimitMgr.checkResourceLimit(account, ResourceType.template);
this._resourceLimitMgr.checkResourceLimit(account, ResourceType.secondary_storage, new Long(srcTmpltStore.getSize()).longValue());
// Event details
final String copyEventType;
if (template.getFormat().equals(ImageFormat.ISO)) {
copyEventType = EventTypes.EVENT_ISO_COPY;
} else {
copyEventType = EventTypes.EVENT_TEMPLATE_COPY;
}
final TemplateInfo srcTemplate = this._tmplFactory.getTemplate(template.getId(), srcSecStore);
// for that zone
for (final DataStore dstSecStore : dstSecStores) {
final TemplateDataStoreVO dstTmpltStore = this._tmplStoreDao.findByStoreTemplate(dstSecStore.getId(), tmpltId);
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() == VMTemplateStatus.DOWNLOADED) {
// already downloaded on this image store
return true;
}
if (dstTmpltStore != null && dstTmpltStore.getDownloadState() != VMTemplateStatus.DOWNLOAD_IN_PROGRESS) {
this._tmplStoreDao.removeByTemplateStore(tmpltId, dstSecStore.getId());
}
final AsyncCallFuture<TemplateApiResult> future = this._tmpltSvr.copyTemplate(srcTemplate, dstSecStore);
try {
final TemplateApiResult result = future.get();
if (result.isFailed()) {
s_logger.debug("copy template failed for image store " + dstSecStore.getName() + ":" + result.getResult());
// try next image store
continue;
}
this._tmpltDao.addTemplateToZone(template, dstZoneId);
return true;
} catch (final Exception ex) {
s_logger.debug("failed to copy template to image store:" + dstSecStore.getName() + " ,will try next one");
}
}
return false;
}
use of com.cloud.legacymodel.exceptions.ResourceAllocationException in project cosmic by MissionCriticalCloud.
the class VolumeServiceImpl method handleVolumeSync.
@Override
public void handleVolumeSync(final DataStore store) {
if (store == null) {
s_logger.warn("Huh? image store is null");
return;
}
final long storeId = store.getId();
// add lock to make template sync for a data store only be done once
final String lockString = "volumesync.storeId:" + storeId;
final GlobalLock syncLock = GlobalLock.getInternLock(lockString);
try {
if (syncLock.lock(3)) {
try {
final Map<Long, TemplateProp> volumeInfos = listVolume(store);
if (volumeInfos == null) {
return;
}
// find all the db volumes including those with NULL url column to avoid accidentally deleting volumes on image store later.
final List<VolumeDataStoreVO> dbVolumes = _volumeStoreDao.listByStoreId(storeId);
final List<VolumeDataStoreVO> toBeDownloaded = new ArrayList<>(dbVolumes);
for (final VolumeDataStoreVO volumeStore : dbVolumes) {
final VolumeVO volume = volDao.findById(volumeStore.getVolumeId());
if (volume == null) {
s_logger.warn("Volume_store_ref table shows that volume " + volumeStore.getVolumeId() + " is on image store " + storeId + ", but the volume is not found in volumes table, potentially some bugs in deleteVolume, so we just treat this volume to be deleted and mark " + "it as destroyed");
volumeStore.setDestroyed(true);
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
continue;
}
// Exists then don't download
if (volumeInfos.containsKey(volume.getId())) {
final TemplateProp volInfo = volumeInfos.remove(volume.getId());
toBeDownloaded.remove(volumeStore);
s_logger.info("Volume Sync found " + volume.getUuid() + " already in the volume image store table");
if (volumeStore.getDownloadState() != VMTemplateStatus.DOWNLOADED) {
volumeStore.setErrorString("");
}
if (volInfo.isCorrupted()) {
volumeStore.setDownloadState(VMTemplateStatus.DOWNLOAD_ERROR);
String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
volumeStore.setErrorString(msg);
s_logger.info(msg);
if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
s_logger.info("Volume Sync found " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + " as corrupted, marking it as " + "failed");
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
// mark volume as failed, so that storage GC will clean it up
final VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
volObj.processEvent(Event.OperationFailed);
} else if (volumeStore.getDownloadUrl() == null) {
msg = "Volume (" + volume.getUuid() + ") with install path " + volInfo.getInstallPath() + " is corrupted, please check in image store: " + volumeStore.getDataStoreId();
s_logger.warn(msg);
} else {
s_logger.info("Removing volume_store_ref entry for corrupted volume " + volume.getName());
_volumeStoreDao.remove(volumeStore.getId());
toBeDownloaded.add(volumeStore);
}
} else {
// Put them in right status
volumeStore.setDownloadPercent(100);
volumeStore.setDownloadState(VMTemplateStatus.DOWNLOADED);
volumeStore.setState(ObjectInDataStoreStateMachine.State.Ready);
volumeStore.setInstallPath(volInfo.getInstallPath());
volumeStore.setSize(volInfo.getSize());
volumeStore.setPhysicalSize(volInfo.getPhysicalSize());
volumeStore.setLastUpdated(new Date());
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
if (volume.getSize() == 0) {
// Set volume size in volumes table
volume.setSize(volInfo.getSize());
volDao.update(volumeStore.getVolumeId(), volume);
}
if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
final VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
volObj.processEvent(Event.OperationSuccessed);
}
if (volInfo.getSize() > 0) {
try {
_resourceLimitMgr.checkResourceLimit(_accountMgr.getAccount(volume.getAccountId()), Resource.ResourceType.secondary_storage, volInfo.getSize() - volInfo.getPhysicalSize());
} catch (final ResourceAllocationException e) {
s_logger.warn(e.getMessage());
_alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_RESOURCE_LIMIT_EXCEEDED, volume.getDataCenterId(), volume.getPodId(), e.getMessage(), e.getMessage());
} finally {
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), Resource.ResourceType.secondary_storage.getOrdinal());
}
}
}
continue;
} else if (volume.getState() == State.NotUploaded || volume.getState() == State.UploadInProgress) {
// failed uploads through SSVM
s_logger.info("Volume Sync did not find " + volume.getUuid() + " uploaded using SSVM on image store " + storeId + ", marking it as failed");
toBeDownloaded.remove(volumeStore);
volumeStore.setDownloadState(VMTemplateStatus.DOWNLOAD_ERROR);
final String msg = "Volume " + volume.getUuid() + " is corrupted on image store";
volumeStore.setErrorString(msg);
_volumeStoreDao.update(volumeStore.getId(), volumeStore);
// mark volume as failed, so that storage GC will clean it up
final VolumeObject volObj = (VolumeObject) volFactory.getVolume(volume.getId());
volObj.processEvent(Event.OperationFailed);
continue;
}
// Volume is not on secondary but we should download.
if (volumeStore.getDownloadState() != VMTemplateStatus.DOWNLOADED) {
s_logger.info("Volume Sync did not find " + volume.getName() + " ready on image store " + storeId + ", will request download to start/resume shortly");
}
}
// Download volumes which haven't been downloaded yet.
if (toBeDownloaded.size() > 0) {
for (final VolumeDataStoreVO volumeHost : toBeDownloaded) {
if (volumeHost.getDownloadUrl() == null) {
// If url is null, skip downloading
s_logger.info("Skip downloading volume " + volumeHost.getVolumeId() + " since no download url is specified.");
continue;
}
// means that this is a duplicate entry from migration of previous NFS to staging.
if (store.getScope().getScopeType() == ScopeType.REGION) {
if (volumeHost.getDownloadState() == VMTemplateStatus.DOWNLOADED && volumeHost.getInstallPath() == null) {
s_logger.info("Skip sync volume for migration of previous NFS to object store");
continue;
}
}
s_logger.debug("Volume " + volumeHost.getVolumeId() + " needs to be downloaded to " + store.getName());
// reset volume status back to Allocated
VolumeObject vol = (VolumeObject) volFactory.getVolume(volumeHost.getVolumeId());
// reset back volume status
vol.processEvent(Event.OperationFailed);
// remove leftover volume_store_ref entry since re-download will create it again
_volumeStoreDao.remove(volumeHost.getId());
// get an updated volumeVO
vol = (VolumeObject) volFactory.getVolume(volumeHost.getVolumeId());
final RegisterVolumePayload payload = new RegisterVolumePayload(volumeHost.getDownloadUrl(), volumeHost.getChecksum(), vol.getFormat().toString());
vol.addPayload(payload);
createVolumeAsync(vol, store);
}
}
// Delete volumes which are not present on DB.
for (final Map.Entry<Long, TemplateProp> entry : volumeInfos.entrySet()) {
final Long uniqueName = entry.getKey();
final TemplateProp tInfo = entry.getValue();
// we cannot directly call expungeVolumeAsync here to reuse delete logic since in this case db does not have this volume at all.
final VolumeObjectTO tmplTO = new VolumeObjectTO();
tmplTO.setDataStore(store.getTO());
tmplTO.setPath(tInfo.getInstallPath());
tmplTO.setId(tInfo.getId());
final DeleteCommand dtCommand = new DeleteCommand(tmplTO);
final EndPoint ep = _epSelector.select(store);
Answer answer = null;
if (ep == null) {
final String errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
s_logger.error(errMsg);
answer = new Answer(dtCommand, false, errMsg);
} else {
answer = ep.sendMessage(dtCommand);
}
if (answer == null || !answer.getResult()) {
s_logger.info("Failed to deleted volume at store: " + store.getName());
} else {
final String description = "Deleted volume " + tInfo.getTemplateName() + " on secondary storage " + storeId;
s_logger.info(description);
}
}
} finally {
syncLock.unlock();
}
} else {
s_logger.info("Couldn't get global lock on " + lockString + ", another thread may be doing volume sync on data store " + storeId + " now.");
}
} finally {
syncLock.releaseRef();
}
}
Aggregations