use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class StorageSystemDataMotionStrategy method handleCreateVolumeFromSnapshotOnSecondaryStorage.
/**
* Creates a volume on the storage from a snapshot that resides on the secondary storage (archived snapshot).
* @param snapshotInfo snapshot on secondary
* @param volumeInfo volume to be created on the storage
* @param callback for async
*/
private void handleCreateVolumeFromSnapshotOnSecondaryStorage(SnapshotInfo snapshotInfo, VolumeInfo volumeInfo, AsyncCompletionCallback<CopyCommandResult> callback) {
// at this point, the snapshotInfo and volumeInfo should have the same disk offering ID (so either one should be OK to get a DiskOfferingVO instance)
DiskOfferingVO diskOffering = _diskOfferingDao.findByIdIncludingRemoved(volumeInfo.getDiskOfferingId());
SnapshotVO snapshot = _snapshotDao.findById(snapshotInfo.getId());
// update the volume's hv_ss_reserve (hypervisor snapshot reserve) from a disk offering (used for managed storage)
_volumeService.updateHypervisorSnapshotReserveForVolume(diskOffering, volumeInfo.getId(), snapshot.getHypervisorType());
CopyCmdAnswer copyCmdAnswer = null;
String errMsg = null;
HostVO hostVO = null;
try {
// create a volume on the storage
AsyncCallFuture<VolumeApiResult> future = _volumeService.createVolumeAsync(volumeInfo, volumeInfo.getDataStore());
VolumeApiResult result = future.get();
if (result.isFailed()) {
LOGGER.error("Failed to create a volume: " + result.getResult());
throw new CloudRuntimeException(result.getResult());
}
volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
volumeInfo.processEvent(Event.MigrationRequested);
volumeInfo = _volumeDataFactory.getVolume(volumeInfo.getId(), volumeInfo.getDataStore());
hostVO = getHost(snapshotInfo.getDataCenterId(), false);
// copy the volume from secondary via the hypervisor
copyCmdAnswer = performCopyOfVdi(volumeInfo, snapshotInfo, hostVO);
if (copyCmdAnswer == null || !copyCmdAnswer.getResult()) {
if (copyCmdAnswer != null && !StringUtils.isEmpty(copyCmdAnswer.getDetails())) {
errMsg = copyCmdAnswer.getDetails();
} else {
errMsg = "Unable to create volume from snapshot";
}
}
} catch (Exception ex) {
errMsg = ex.getMessage() != null ? ex.getMessage() : "Copy operation failed in 'StorageSystemDataMotionStrategy.handleCreateVolumeFromSnapshotBothOnStorageSystem'";
}
CopyCommandResult result = new CopyCommandResult(null, copyCmdAnswer);
result.setResult(errMsg);
callback.complete(result);
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class UserVmManagerImpl method restoreVMInternal.
public UserVm restoreVMInternal(Account caller, UserVmVO vm, Long newTemplateId) throws InsufficientCapacityException, ResourceUnavailableException {
Long userId = caller.getId();
Account owner = _accountDao.findById(vm.getAccountId());
_userDao.findById(userId);
long vmId = vm.getId();
boolean needRestart = false;
// Input validation
if (owner == null) {
throw new InvalidParameterValueException("The owner of " + vm + " does not exist: " + vm.getAccountId());
}
if (owner.getState() == Account.State.disabled) {
throw new PermissionDeniedException("The owner of " + vm + " is disabled: " + vm.getAccountId());
}
if (vm.getState() != VirtualMachine.State.Running && vm.getState() != VirtualMachine.State.Stopped) {
throw new CloudRuntimeException("Vm " + vm.getUuid() + " currently in " + vm.getState() + " state, restore vm can only execute when VM in Running or Stopped");
}
if (vm.getState() == VirtualMachine.State.Running) {
needRestart = true;
}
List<VolumeVO> rootVols = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
if (rootVols.isEmpty()) {
InvalidParameterValueException ex = new InvalidParameterValueException("Can not find root volume for VM " + vm.getUuid());
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
if (rootVols.size() > 1) {
InvalidParameterValueException ex = new InvalidParameterValueException("There are " + rootVols.size() + " root volumes for VM " + vm.getUuid());
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
VolumeVO root = rootVols.get(0);
if (!Volume.State.Allocated.equals(root.getState()) || newTemplateId != null) {
Long templateId = root.getTemplateId();
boolean isISO = false;
if (templateId == null) {
// Assuming that for a vm deployed using ISO, template ID is set to NULL
isISO = true;
templateId = vm.getIsoId();
}
// If target VM has associated VM snapshots then don't allow restore of VM
List<VMSnapshotVO> vmSnapshots = _vmSnapshotDao.findByVm(vmId);
if (vmSnapshots.size() > 0) {
throw new InvalidParameterValueException("Unable to restore VM, please remove VM snapshots before restoring VM");
}
VMTemplateVO template = null;
//newTemplateId can be either template or ISO id. In the following snippet based on the vm deployment (from template or ISO) it is handled accordingly
if (newTemplateId != null) {
template = _templateDao.findById(newTemplateId);
_accountMgr.checkAccess(caller, null, true, template);
if (isISO) {
if (!template.getFormat().equals(ImageFormat.ISO)) {
throw new InvalidParameterValueException("Invalid ISO id provided to restore the VM ");
}
} else {
if (template.getFormat().equals(ImageFormat.ISO)) {
throw new InvalidParameterValueException("Invalid template id provided to restore the VM ");
}
}
} else {
if (isISO && templateId == null) {
throw new CloudRuntimeException("Cannot restore the VM since there is no ISO attached to VM");
}
template = _templateDao.findById(templateId);
if (template == null) {
InvalidParameterValueException ex = new InvalidParameterValueException("Cannot find template/ISO for specified volumeid and vmId");
ex.addProxyObject(vm.getUuid(), "vmId");
ex.addProxyObject(root.getUuid(), "volumeId");
throw ex;
}
}
TemplateDataStoreVO tmplStore = _templateStoreDao.findByTemplateZoneReady(template.getId(), vm.getDataCenterId());
if (tmplStore == null) {
throw new InvalidParameterValueException("Cannot restore the vm as the template " + template.getUuid() + " isn't available in the zone");
}
if (needRestart) {
try {
_itMgr.stop(vm.getUuid());
} catch (ResourceUnavailableException e) {
s_logger.debug("Stop vm " + vm.getUuid() + " failed", e);
CloudRuntimeException ex = new CloudRuntimeException("Stop vm failed for specified vmId");
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
}
/* If new template/ISO is provided allocate a new volume from new template/ISO otherwise allocate new volume from original template/ISO */
Volume newVol = null;
if (newTemplateId != null) {
if (isISO) {
newVol = volumeMgr.allocateDuplicateVolume(root, null);
vm.setIsoId(newTemplateId);
vm.setGuestOSId(template.getGuestOSId());
vm.setTemplateId(newTemplateId);
_vmDao.update(vmId, vm);
} else {
newVol = volumeMgr.allocateDuplicateVolume(root, newTemplateId);
vm.setGuestOSId(template.getGuestOSId());
vm.setTemplateId(newTemplateId);
_vmDao.update(vmId, vm);
}
} else {
newVol = volumeMgr.allocateDuplicateVolume(root, null);
}
// 1. Save usage event and update resource count for user vm volumes
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.volume, newVol.isDisplay());
_resourceLimitMgr.incrementResourceCount(newVol.getAccountId(), ResourceType.primary_storage, newVol.isDisplay(), new Long(newVol.getSize()));
// 2. Create Usage event for the newly created volume
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VOLUME_CREATE, newVol.getAccountId(), newVol.getDataCenterId(), newVol.getId(), newVol.getName(), newVol.getDiskOfferingId(), template.getId(), newVol.getSize());
_usageEventDao.persist(usageEvent);
handleManagedStorage(vm, root);
_volsDao.attachVolume(newVol.getId(), vmId, newVol.getDeviceId());
// Detach, destroy and create the usage event for the old root volume.
_volsDao.detachVolume(root.getId());
volumeMgr.destroyVolume(root);
// For VMware hypervisor since the old root volume is replaced by the new root volume, force expunge old root volume if it has been created in storage
if (vm.getHypervisorType() == HypervisorType.VMware) {
VolumeInfo volumeInStorage = volFactory.getVolume(root.getId());
if (volumeInStorage != null) {
s_logger.info("Expunging volume " + root.getId() + " from primary data store");
AsyncCallFuture<VolumeApiResult> future = _volService.expungeVolumeAsync(volFactory.getVolume(root.getId()));
try {
future.get();
} catch (Exception e) {
s_logger.debug("Failed to expunge volume:" + root.getId(), e);
}
}
}
Map<VirtualMachineProfile.Param, Object> params = null;
String password = null;
if (template.getEnablePassword()) {
password = _mgr.generateRandomPassword();
boolean result = resetVMPasswordInternal(vmId, password);
if (result) {
vm.setPassword(password);
_vmDao.loadDetails(vm);
// update the password in vm_details table too
// Check if an SSH key pair was selected for the instance and if so
// use it to encrypt & save the vm password
encryptAndStorePassword(vm, password);
} else {
throw new CloudRuntimeException("VM reset is completed but failed to reset password for the virtual machine ");
}
}
if (needRestart) {
try {
if (vm.getDetail("password") != null) {
params = new HashMap<VirtualMachineProfile.Param, Object>();
params.put(VirtualMachineProfile.Param.VmPassword, password);
}
_itMgr.start(vm.getUuid(), params);
vm = _vmDao.findById(vmId);
if (template.getEnablePassword()) {
// this value is not being sent to the backend; need only for api
// display purposes
vm.setPassword(password);
if (vm.isUpdateParameters()) {
vm.setUpdateParameters(false);
_vmDao.loadDetails(vm);
if (vm.getDetail("password") != null) {
_vmDetailsDao.remove(_vmDetailsDao.findDetail(vm.getId(), "password").getId());
}
_vmDao.update(vm.getId(), vm);
}
}
} catch (Exception e) {
s_logger.debug("Unable to start VM " + vm.getUuid(), e);
CloudRuntimeException ex = new CloudRuntimeException("Unable to start VM with specified id" + e.getMessage());
ex.addProxyObject(vm.getUuid(), "vmId");
throw ex;
}
}
}
s_logger.debug("Restore VM " + vmId + " done successfully");
return vm;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class StorageManagerImpl method deletePool.
@Override
@DB
public boolean deletePool(DeletePoolCmd cmd) {
Long id = cmd.getId();
boolean forced = cmd.isForced();
StoragePoolVO sPool = _storagePoolDao.findById(id);
if (sPool == null) {
s_logger.warn("Unable to find pool:" + id);
throw new InvalidParameterValueException("Unable to find pool by id " + id);
}
if (sPool.getStatus() != StoragePoolStatus.Maintenance) {
s_logger.warn("Unable to delete storage id: " + id + " due to it is not in Maintenance state");
throw new InvalidParameterValueException("Unable to delete storage due to it is not in Maintenance state, id: " + id);
}
if (sPool.isLocal()) {
s_logger.warn("Unable to delete local storage id:" + id);
throw new InvalidParameterValueException("Unable to delete local storage id: " + id);
}
Pair<Long, Long> vlms = _volsDao.getCountAndTotalByPool(id);
if (forced) {
if (vlms.first() > 0) {
Pair<Long, Long> nonDstrdVlms = _volsDao.getNonDestroyedCountAndTotalByPool(id);
if (nonDstrdVlms.first() > 0) {
throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated " + "non-destroyed vols for this pool");
}
// force expunge non-destroyed volumes
List<VolumeVO> vols = _volsDao.listVolumesToBeDestroyed();
for (VolumeVO vol : vols) {
AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volFactory.getVolume(vol.getId()));
try {
future.get();
} catch (InterruptedException e) {
s_logger.debug("expunge volume failed:" + vol.getId(), e);
} catch (ExecutionException e) {
s_logger.debug("expunge volume failed:" + vol.getId(), e);
}
}
}
} else {
// If it does , then you cannot delete the pool
if (vlms.first() > 0) {
throw new CloudRuntimeException("Cannot delete pool " + sPool.getName() + " as there are associated volumes for this pool");
}
}
// First get the host_id from storage_pool_host_ref for given pool id
StoragePoolVO lock = _storagePoolDao.acquireInLockTable(sPool.getId());
if (lock == null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Failed to acquire lock when deleting PrimaryDataStoreVO with ID: " + sPool.getId());
}
return false;
}
_storagePoolDao.releaseFromLockTable(lock.getId());
s_logger.trace("Released lock for storage pool " + id);
DataStoreProvider storeProvider = _dataStoreProviderMgr.getDataStoreProvider(sPool.getStorageProviderName());
DataStoreLifeCycle lifeCycle = storeProvider.getDataStoreLifeCycle();
DataStore store = _dataStoreMgr.getDataStore(sPool.getId(), DataStoreRole.Primary);
return lifeCycle.deleteDataStore(store);
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class VolumeApiServiceImpl method deleteVolume.
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_DELETE, eventDescription = "deleting volume")
public boolean deleteVolume(long volumeId, Account caller) throws ConcurrentOperationException {
VolumeVO volume = _volsDao.findById(volumeId);
if (volume == null) {
throw new InvalidParameterValueException("Unable to find volume with ID: " + volumeId);
}
if (!_snapshotMgr.canOperateOnVolume(volume)) {
throw new InvalidParameterValueException("There are snapshot operations in progress on the volume, unable to delete it");
}
_accountMgr.checkAccess(caller, null, true, volume);
if (volume.getInstanceId() != null) {
throw new InvalidParameterValueException("Please specify a volume that is not attached to any VM.");
}
if (volume.getState() == Volume.State.UploadOp) {
VolumeDataStoreVO volumeStore = _volumeStoreDao.findByVolume(volume.getId());
if (volumeStore.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOAD_IN_PROGRESS) {
throw new InvalidParameterValueException("Please specify a volume that is not uploading");
}
}
if (volume.getState() == Volume.State.NotUploaded || volume.getState() == Volume.State.UploadInProgress) {
throw new InvalidParameterValueException("The volume is either getting uploaded or it may be initiated shortly, please wait for it to be completed");
}
try {
if (volume.getState() != Volume.State.Destroy && volume.getState() != Volume.State.Expunging && volume.getState() != Volume.State.Expunged) {
Long instanceId = volume.getInstanceId();
if (!volService.destroyVolume(volume.getId())) {
return false;
}
VMInstanceVO vmInstance = _vmInstanceDao.findById(instanceId);
if (instanceId == null || (vmInstance.getType().equals(VirtualMachine.Type.User))) {
// Decrement the resource count for volumes and primary storage belonging user VM's only
_resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, volume.isDisplayVolume());
}
}
// Mark volume as removed if volume has not been created on primary or secondary
if (volume.getState() == Volume.State.Allocated) {
_volsDao.remove(volumeId);
stateTransitTo(volume, Volume.Event.DestroyRequested);
return true;
}
// expunge volume from primary if volume is on primary
VolumeInfo volOnPrimary = volFactory.getVolume(volume.getId(), DataStoreRole.Primary);
if (volOnPrimary != null) {
s_logger.info("Expunging volume " + volume.getId() + " from primary data store");
AsyncCallFuture<VolumeApiResult> future = volService.expungeVolumeAsync(volOnPrimary);
future.get();
//decrement primary storage count
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.primary_storage.getOrdinal());
}
// expunge volume from secondary if volume is on image store
VolumeInfo volOnSecondary = volFactory.getVolume(volume.getId(), DataStoreRole.Image);
if (volOnSecondary != null) {
s_logger.info("Expunging volume " + volume.getId() + " from secondary data store");
AsyncCallFuture<VolumeApiResult> future2 = volService.expungeVolumeAsync(volOnSecondary);
future2.get();
//decrement secondary storage count
_resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.secondary_storage.getOrdinal());
}
// delete all cache entries for this volume
List<VolumeInfo> cacheVols = volFactory.listVolumeOnCache(volume.getId());
for (VolumeInfo volOnCache : cacheVols) {
s_logger.info("Delete volume from image cache store: " + volOnCache.getDataStore().getName());
volOnCache.delete();
}
} catch (InterruptedException | ExecutionException | NoTransitionException e) {
s_logger.warn("Failed to expunge volume:", e);
return false;
}
return true;
}
use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult in project cloudstack by apache.
the class VolumeTest method testDeleteDisk.
@Test
public void testDeleteDisk() throws InterruptedException, ExecutionException, ConcurrentOperationException {
DataStore primaryStore = createPrimaryDataStore();
primaryStoreId = primaryStore.getId();
primaryStore = this.dataStoreMgr.getPrimaryDataStore(primaryStoreId);
VolumeVO volume = createVolume(null, primaryStore.getId());
VolumeInfo volInfo = this.volFactory.getVolume(volume.getId());
AsyncCallFuture<VolumeApiResult> future = this.volumeService.createVolumeAsync(volInfo, primaryStore);
VolumeApiResult result = future.get();
Assert.assertTrue(result.isSuccess());
VolumeInfo vol = result.getVolume();
boolean res = this.volumeService.destroyVolume(volInfo.getId());
Assert.assertTrue(res);
volInfo = this.volFactory.getVolume(vol.getId());
future = this.volumeService.expungeVolumeAsync(volInfo);
result = future.get();
Assert.assertTrue(result.isSuccess());
}
Aggregations