Search in sources :

Example 66 with VolumeInfo

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.

the class VolumeApiServiceImpl method allocSnapshotForVm.

@Override
public Snapshot allocSnapshotForVm(Long vmId, Long volumeId, String snapshotName) throws ResourceAllocationException {
    Account caller = CallContext.current().getCallingAccount();
    VMInstanceVO vm = _vmInstanceDao.findById(vmId);
    if (vm == null) {
        throw new InvalidParameterValueException("Creating snapshot failed due to vm:" + vmId + " doesn't exist");
    }
    _accountMgr.checkAccess(caller, null, true, vm);
    VolumeInfo volume = volFactory.getVolume(volumeId);
    if (volume == null) {
        throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't exist");
    }
    _accountMgr.checkAccess(caller, null, true, volume);
    VirtualMachine attachVM = volume.getAttachedVM();
    if (attachVM == null || attachVM.getId() != vm.getId()) {
        throw new InvalidParameterValueException("Creating snapshot failed due to volume:" + volumeId + " doesn't attach to vm :" + vm);
    }
    DataCenter zone = _dcDao.findById(volume.getDataCenterId());
    if (zone == null) {
        throw new InvalidParameterValueException("Can't find zone by id " + volume.getDataCenterId());
    }
    if (Grouping.AllocationState.Disabled == zone.getAllocationState() && !_accountMgr.isRootAdmin(caller.getId())) {
        throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: " + zone.getName());
    }
    if (volume.getState() != Volume.State.Ready) {
        throw new InvalidParameterValueException("VolumeId: " + volumeId + " is not in " + Volume.State.Ready + " state but " + volume.getState() + ". Cannot take snapshot.");
    }
    if (volume.getTemplateId() != null) {
        VMTemplateVO template = _templateDao.findById(volume.getTemplateId());
        if (template != null && template.getTemplateType() == Storage.TemplateType.SYSTEM) {
            throw new InvalidParameterValueException("VolumeId: " + volumeId + " is for System VM , Creating snapshot against System VM volumes is not supported");
        }
    }
    StoragePool storagePool = (StoragePool) volume.getDataStore();
    if (storagePool == null) {
        throw new InvalidParameterValueException("VolumeId: " + volumeId + " please attach this volume to a VM before create snapshot for it");
    }
    return snapshotMgr.allocSnapshot(volumeId, Snapshot.MANUAL_POLICY_ID, snapshotName, null);
}
Also used : Account(com.cloud.user.Account) DataCenter(com.cloud.dc.DataCenter) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) VMInstanceVO(com.cloud.vm.VMInstanceVO) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) VirtualMachine(com.cloud.vm.VirtualMachine)

Example 67 with VolumeInfo

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.

the class VolumeApiServiceImpl method orchestrateAttachVolumeToVM.

private Volume orchestrateAttachVolumeToVM(Long vmId, Long volumeId, Long deviceId) {
    VolumeInfo volumeToAttach = volFactory.getVolume(volumeId);
    if (volumeToAttach.isAttachedVM()) {
        throw new CloudRuntimeException("This volume is already attached to a VM.");
    }
    UserVmVO vm = _userVmDao.findById(vmId);
    VolumeVO exstingVolumeOfVm = null;
    List<VolumeVO> rootVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.ROOT);
    if (rootVolumesOfVm.size() > 1) {
        throw new CloudRuntimeException("The VM " + vm.getHostName() + " has more than one ROOT volume and is in an invalid state.");
    } else {
        if (!rootVolumesOfVm.isEmpty()) {
            exstingVolumeOfVm = rootVolumesOfVm.get(0);
        } else {
            // locate data volume of the vm
            List<VolumeVO> diskVolumesOfVm = _volsDao.findByInstanceAndType(vmId, Volume.Type.DATADISK);
            for (VolumeVO diskVolume : diskVolumesOfVm) {
                if (diskVolume.getState() != Volume.State.Allocated) {
                    exstingVolumeOfVm = diskVolume;
                    break;
                }
            }
        }
    }
    HypervisorType rootDiskHyperType = vm.getHypervisorType();
    HypervisorType volumeToAttachHyperType = _volsDao.getHypervisorType(volumeToAttach.getId());
    VolumeInfo newVolumeOnPrimaryStorage = volumeToAttach;
    //don't create volume on primary storage if its being attached to the vm which Root's volume hasn't been created yet
    StoragePoolVO destPrimaryStorage = null;
    if (exstingVolumeOfVm != null && !exstingVolumeOfVm.getState().equals(Volume.State.Allocated)) {
        destPrimaryStorage = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
    }
    boolean volumeOnSecondary = volumeToAttach.getState() == Volume.State.Uploaded;
    if (destPrimaryStorage != null && (volumeToAttach.getState() == Volume.State.Allocated || volumeOnSecondary)) {
        try {
            newVolumeOnPrimaryStorage = _volumeMgr.createVolumeOnPrimaryStorage(vm, volumeToAttach, rootDiskHyperType, destPrimaryStorage);
        } catch (NoTransitionException e) {
            s_logger.debug("Failed to create volume on primary storage", e);
            throw new CloudRuntimeException("Failed to create volume on primary storage", e);
        }
    }
    // reload the volume from db
    newVolumeOnPrimaryStorage = volFactory.getVolume(newVolumeOnPrimaryStorage.getId());
    boolean moveVolumeNeeded = needMoveVolume(exstingVolumeOfVm, newVolumeOnPrimaryStorage);
    if (moveVolumeNeeded) {
        PrimaryDataStoreInfo primaryStore = (PrimaryDataStoreInfo) newVolumeOnPrimaryStorage.getDataStore();
        if (primaryStore.isLocal()) {
            throw new CloudRuntimeException("Failed to attach local data volume " + volumeToAttach.getName() + " to VM " + vm.getDisplayName() + " as migration of local data volume is not allowed");
        }
        StoragePoolVO vmRootVolumePool = _storagePoolDao.findById(exstingVolumeOfVm.getPoolId());
        try {
            newVolumeOnPrimaryStorage = _volumeMgr.moveVolume(newVolumeOnPrimaryStorage, vmRootVolumePool.getDataCenterId(), vmRootVolumePool.getPodId(), vmRootVolumePool.getClusterId(), volumeToAttachHyperType);
        } catch (ConcurrentOperationException e) {
            s_logger.debug("move volume failed", e);
            throw new CloudRuntimeException("move volume failed", e);
        } catch (StorageUnavailableException e) {
            s_logger.debug("move volume failed", e);
            throw new CloudRuntimeException("move volume failed", e);
        }
    }
    VolumeVO newVol = _volsDao.findById(newVolumeOnPrimaryStorage.getId());
    // Getting the fresh vm object in case of volume migration to check the current state of VM
    if (moveVolumeNeeded || volumeOnSecondary) {
        vm = _userVmDao.findById(vmId);
        if (vm == null) {
            throw new InvalidParameterValueException("VM not found.");
        }
    }
    newVol = sendAttachVolumeCommand(vm, newVol, deviceId);
    return newVol;
}
Also used : PrimaryDataStoreInfo(org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStoreInfo) UserVmVO(com.cloud.vm.UserVmVO) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO)

Example 68 with VolumeInfo

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.

the class VolumeApiServiceImpl method liveMigrateVolume.

@DB
protected Volume liveMigrateVolume(Volume volume, StoragePool destPool) throws StorageUnavailableException {
    VolumeInfo vol = volFactory.getVolume(volume.getId());
    AsyncCallFuture<VolumeApiResult> future = volService.migrateVolume(vol, (DataStore) destPool);
    try {
        VolumeApiResult result = future.get();
        if (result.isFailed()) {
            s_logger.debug("migrate volume failed:" + result.getResult());
            throw new StorageUnavailableException("Migrate volume failed: " + result.getResult(), destPool.getId());
        }
        return result.getVolume();
    } catch (InterruptedException e) {
        s_logger.debug("migrate volume failed", e);
        throw new CloudRuntimeException(e.getMessage());
    } catch (ExecutionException e) {
        s_logger.debug("migrate volume failed", e);
        throw new CloudRuntimeException(e.getMessage());
    }
}
Also used : StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) VolumeApiResult(org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult) ExecutionException(java.util.concurrent.ExecutionException) DB(com.cloud.utils.db.DB)

Example 69 with VolumeInfo

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.

the class VolumeApiServiceImpl method createVolume.

@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_CREATE, eventDescription = "creating volume", async = true)
public VolumeVO createVolume(CreateVolumeCmd cmd) {
    VolumeVO volume = _volsDao.findById(cmd.getEntityId());
    boolean created = true;
    try {
        if (cmd.getSnapshotId() != null) {
            volume = createVolumeFromSnapshot(volume, cmd.getSnapshotId(), cmd.getVirtualMachineId());
            if (volume.getState() != Volume.State.Ready) {
                created = false;
            }
            // if VM Id is provided, attach the volume to the VM
            if (cmd.getVirtualMachineId() != null) {
                try {
                    attachVolumeToVM(cmd.getVirtualMachineId(), volume.getId(), volume.getDeviceId());
                } catch (Exception ex) {
                    StringBuilder message = new StringBuilder("Volume: ");
                    message.append(volume.getUuid());
                    message.append(" created successfully, but failed to attach the newly created volume to VM: ");
                    message.append(cmd.getVirtualMachineId());
                    message.append(" due to error: ");
                    message.append(ex.getMessage());
                    if (s_logger.isDebugEnabled()) {
                        s_logger.debug(message, ex);
                    }
                    throw new CloudRuntimeException(message.toString());
                }
            }
        }
        return volume;
    } catch (Exception e) {
        created = false;
        VolumeInfo vol = volFactory.getVolume(cmd.getEntityId());
        vol.stateTransit(Volume.Event.DestroyRequested);
        throw new CloudRuntimeException("Failed to create volume: " + volume.getId(), e);
    } finally {
        if (!created) {
            s_logger.trace("Decrementing volume resource count for account id=" + volume.getAccountId() + " as volume failed to create on the backend");
            _resourceLimitMgr.decrementResourceCount(volume.getAccountId(), ResourceType.volume, cmd.getDisplayVolume());
            _resourceLimitMgr.recalculateResourceCount(volume.getAccountId(), volume.getDomainId(), ResourceType.primary_storage.getOrdinal());
        }
    }
}
Also used : CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) NoTransitionException(com.cloud.utils.fsm.NoTransitionException) TransactionCallbackWithException(com.cloud.utils.db.TransactionCallbackWithException) StorageUnavailableException(com.cloud.exception.StorageUnavailableException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) ExecutionException(java.util.concurrent.ExecutionException) InvalidParameterValueException(com.cloud.exception.InvalidParameterValueException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) ConcurrentOperationException(com.cloud.exception.ConcurrentOperationException) JsonParseException(com.google.gson.JsonParseException) PermissionDeniedException(com.cloud.exception.PermissionDeniedException) MalformedURLException(java.net.MalformedURLException) ActionEvent(com.cloud.event.ActionEvent) DB(com.cloud.utils.db.DB)

Example 70 with VolumeInfo

use of org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo in project cloudstack by apache.

the class SnapshotManagerImpl method allocSnapshot.

@Override
public Snapshot allocSnapshot(Long volumeId, Long policyId, String snapshotName, Snapshot.LocationType locationType) throws ResourceAllocationException {
    Account caller = CallContext.current().getCallingAccount();
    VolumeInfo volume = volFactory.getVolume(volumeId);
    supportedByHypervisor(volume);
    // Verify permissions
    _accountMgr.checkAccess(caller, null, true, volume);
    Type snapshotType = getSnapshotType(policyId);
    Account owner = _accountMgr.getAccount(volume.getAccountId());
    try {
        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.snapshot);
        _resourceLimitMgr.checkResourceLimit(owner, ResourceType.secondary_storage, new Long(volume.getSize()).longValue());
    } catch (ResourceAllocationException e) {
        if (snapshotType != Type.MANUAL) {
            String msg = "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots";
            s_logger.warn(msg);
            _alertMgr.sendAlert(AlertManager.AlertType.ALERT_TYPE_UPDATE_RESOURCE_COUNT, 0L, 0L, msg, "Snapshot resource limit exceeded for account id : " + owner.getId() + ". Failed to create recurring snapshots; please use updateResourceLimit to increase the limit");
        }
        throw e;
    }
    // Determine the name for this snapshot
    // Snapshot Name: VMInstancename + volumeName + timeString
    String timeString = DateUtil.getDateDisplayString(DateUtil.GMT_TIMEZONE, new Date(), DateUtil.YYYYMMDD_FORMAT);
    VMInstanceVO vmInstance = _vmDao.findById(volume.getInstanceId());
    String vmDisplayName = "detached";
    if (vmInstance != null) {
        vmDisplayName = vmInstance.getHostName();
    }
    if (snapshotName == null)
        snapshotName = vmDisplayName + "_" + volume.getName() + "_" + timeString;
    HypervisorType hypervisorType = HypervisorType.None;
    StoragePoolVO storagePool = _storagePoolDao.findById(volume.getDataStore().getId());
    if (storagePool.getScope() == ScopeType.ZONE) {
        hypervisorType = storagePool.getHypervisor();
        // at the time being, managed storage only supports XenServer, ESX(i), and KVM (i.e. not Hyper-V), so the VHD file type can be mapped to XenServer
        if (storagePool.isManaged() && HypervisorType.Any.equals(hypervisorType) && ImageFormat.VHD.equals(volume.getFormat())) {
            hypervisorType = HypervisorType.XenServer;
        }
    } else {
        hypervisorType = volume.getHypervisorType();
    }
    SnapshotVO snapshotVO = new SnapshotVO(volume.getDataCenterId(), volume.getAccountId(), volume.getDomainId(), volume.getId(), volume.getDiskOfferingId(), snapshotName, (short) snapshotType.ordinal(), snapshotType.name(), volume.getSize(), volume.getMinIops(), volume.getMaxIops(), hypervisorType, locationType);
    SnapshotVO snapshot = _snapshotDao.persist(snapshotVO);
    if (snapshot == null) {
        throw new CloudRuntimeException("Failed to create snapshot for volume: " + volume.getId());
    }
    _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.snapshot);
    _resourceLimitMgr.incrementResourceCount(volume.getAccountId(), ResourceType.secondary_storage, new Long(volume.getSize()));
    return snapshot;
}
Also used : HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) Account(com.cloud.user.Account) ScopeType(com.cloud.storage.ScopeType) Type(com.cloud.storage.Snapshot.Type) HypervisorType(com.cloud.hypervisor.Hypervisor.HypervisorType) ResourceType(com.cloud.configuration.Resource.ResourceType) IntervalType(com.cloud.utils.DateUtil.IntervalType) ResourceObjectType(com.cloud.server.ResourceTag.ResourceObjectType) VMSnapshotVO(com.cloud.vm.snapshot.VMSnapshotVO) SnapshotVO(com.cloud.storage.SnapshotVO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StoragePoolVO(org.apache.cloudstack.storage.datastore.db.StoragePoolVO) VMInstanceVO(com.cloud.vm.VMInstanceVO) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) Date(java.util.Date)

Aggregations

VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)112 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)51 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)50 VolumeVO (com.cloud.storage.VolumeVO)36 ConcurrentOperationException (com.cloud.exception.ConcurrentOperationException)23 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)22 ExecutionException (java.util.concurrent.ExecutionException)22 VolumeApiResult (org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult)22 InvalidParameterValueException (com.cloud.exception.InvalidParameterValueException)19 StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)19 CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)18 SnapshotInfo (org.apache.cloudstack.engine.subsystem.api.storage.SnapshotInfo)17 ArrayList (java.util.ArrayList)15 HashMap (java.util.HashMap)15 StorageUnavailableException (com.cloud.exception.StorageUnavailableException)13 Map (java.util.Map)13 SnapshotVO (com.cloud.storage.SnapshotVO)12 DB (com.cloud.utils.db.DB)12 Test (org.testng.annotations.Test)12 Account (com.cloud.user.Account)11