Search in sources :

Example 66 with CopyCommandResult

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

the class VolumeServiceImpl method copyTemplateToManagedTemplateVolume.

/**
 * This function copies a template from secondary storage to a template volume
 * created on managed storage. This template volume will be used as a cache.
 * Instead of copying the template to a ROOT volume every time, a clone is performed instead.
 *
 * @param srcTemplateInfo Source from which to copy the template
 * @param templateOnPrimary Dest to copy to
 * @param templatePoolRef Template reference on primary storage (entry in the template_spool_ref)
 * @param destPrimaryDataStore The managed primary storage
 * @param destHost The host that we will use for the copy
 */
private void copyTemplateToManagedTemplateVolume(TemplateInfo srcTemplateInfo, TemplateInfo templateOnPrimary, VMTemplateStoragePoolVO templatePoolRef, PrimaryDataStore destPrimaryDataStore, Host destHost) throws StorageAccessException {
    AsyncCallFuture<VolumeApiResult> copyTemplateFuture = new AsyncCallFuture<>();
    int storagePoolMaxWaitSeconds = NumbersUtil.parseInt(configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
    long templatePoolRefId = templatePoolRef.getId();
    try {
        templatePoolRef = _tmpltPoolDao.acquireInLockTable(templatePoolRefId, storagePoolMaxWaitSeconds);
        if (templatePoolRef == null) {
            throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templatePoolRefId);
        }
        if (templatePoolRef.getDownloadState() == Status.DOWNLOADED) {
            // There can be cases where we acquired the lock, but the template
            // was already copied by a previous thread. Just return in that case.
            s_logger.debug("Template already downloaded, nothing to do");
            return;
        }
        // copy the template from sec storage to the created volume
        CreateBaseImageContext<CreateCmdResult> copyContext = new CreateBaseImageContext<>(null, null, destPrimaryDataStore, srcTemplateInfo, copyTemplateFuture, templateOnPrimary, templatePoolRefId);
        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> copyCaller = AsyncCallbackDispatcher.create(this);
        copyCaller.setCallback(copyCaller.getTarget().copyManagedTemplateCallback(null, null)).setContext(copyContext);
        // Populate details which will be later read by the storage subsystem.
        Map<String, String> details = new HashMap<>();
        details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
        details.put(PrimaryDataStore.STORAGE_HOST, destPrimaryDataStore.getHostAddress());
        details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(destPrimaryDataStore.getPort()));
        details.put(PrimaryDataStore.MANAGED_STORE_TARGET, templateOnPrimary.getInstallPath());
        details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, srcTemplateInfo.getUniqueName());
        details.put(PrimaryDataStore.REMOVE_AFTER_COPY, Boolean.TRUE.toString());
        details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(templateOnPrimary.getSize()));
        details.put(StorageManager.STORAGE_POOL_DISK_WAIT.toString(), String.valueOf(StorageManager.STORAGE_POOL_DISK_WAIT.valueIn(destPrimaryDataStore.getId())));
        ChapInfo chapInfo = getChapInfo(templateOnPrimary, destPrimaryDataStore);
        if (chapInfo != null) {
            details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
            details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
            details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
            details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
        }
        destPrimaryDataStore.setDetails(details);
        try {
            grantAccess(templateOnPrimary, destHost, destPrimaryDataStore);
        } catch (Exception e) {
            throw new StorageAccessException("Unable to grant access to template: " + templateOnPrimary.getId() + " on host: " + destHost.getId());
        }
        templateOnPrimary.processEvent(Event.CopyingRequested);
        VolumeApiResult result;
        try {
            motionSrv.copyAsync(srcTemplateInfo, templateOnPrimary, destHost, copyCaller);
            result = copyTemplateFuture.get();
        } finally {
            revokeAccess(templateOnPrimary, destHost, destPrimaryDataStore);
            if (HypervisorType.VMware.equals(destHost.getHypervisorType())) {
                details.put(ModifyTargetsCommand.IQN, templateOnPrimary.getInstallPath());
                List<Map<String, String>> targets = new ArrayList<>();
                targets.add(details);
                removeDynamicTargets(destHost.getId(), targets);
            }
        }
        if (result.isFailed()) {
            throw new CloudRuntimeException("Failed to copy template " + templateOnPrimary.getId() + " to primary storage " + destPrimaryDataStore.getId() + ": " + result.getResult());
        // XXX: I find it is useful to destroy the volume on primary storage instead of another thread trying the copy again because I've seen
        // something weird happens to the volume (XenServer creates an SR, but the VDI copy can fail).
        // For now, I just retry the copy.
        }
    } catch (StorageAccessException e) {
        throw e;
    } catch (Throwable e) {
        s_logger.debug("Failed to create a template on primary storage", e);
        templateOnPrimary.processEvent(Event.OperationFailed);
        throw new CloudRuntimeException(e.getMessage());
    } finally {
        _tmpltPoolDao.releaseFromLockTable(templatePoolRefId);
    }
}
Also used : HashMap(java.util.HashMap) ChapInfo(org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo) ArrayList(java.util.ArrayList) StorageAccessException(com.cloud.exception.StorageAccessException) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) EndPoint(org.apache.cloudstack.engine.subsystem.api.storage.EndPoint) RemoteHostEndPoint(org.apache.cloudstack.storage.RemoteHostEndPoint) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StorageAccessException(com.cloud.exception.StorageAccessException) ExecutionException(java.util.concurrent.ExecutionException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) AsyncCallFuture(org.apache.cloudstack.framework.async.AsyncCallFuture) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) Map(java.util.Map) HashMap(java.util.HashMap)

Example 67 with CopyCommandResult

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

the class VolumeServiceImpl method migrateVmWithVolumesCallBack.

protected Void migrateVmWithVolumesCallBack(AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> callback, MigrateVmWithVolumesContext<CommandResult> context) {
    Map<VolumeInfo, DataStore> volumeToPool = context.volumeToPool;
    CopyCommandResult result = callback.getResult();
    AsyncCallFuture<CommandResult> future = context.future;
    CommandResult res = new CommandResult();
    try {
        if (result.isFailed()) {
            res.setResult(result.getResult());
            for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
                VolumeInfo volume = entry.getKey();
                volume.processEvent(Event.OperationFailed);
            }
            future.complete(res);
        } else {
            for (Map.Entry<VolumeInfo, DataStore> entry : volumeToPool.entrySet()) {
                VolumeInfo volume = entry.getKey();
                snapshotMgr.cleanupSnapshotsByVolume(volume.getId());
                volume.processEvent(Event.OperationSuccessed);
            }
            future.complete(res);
        }
    } catch (Exception e) {
        s_logger.error("Failed to process copy volume callback", e);
        res.setResult(e.toString());
        future.complete(res);
    }
    return null;
}
Also used : PrimaryDataStore(org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore) DataStore(org.apache.cloudstack.engine.subsystem.api.storage.DataStore) VolumeInfo(org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) Map(java.util.Map) HashMap(java.util.HashMap) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StorageAccessException(com.cloud.exception.StorageAccessException) ExecutionException(java.util.concurrent.ExecutionException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult) CommandResult(org.apache.cloudstack.storage.command.CommandResult)

Example 68 with CopyCommandResult

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

the class VolumeServiceImpl method createManagedVolumeCopyTemplateAsync.

private void createManagedVolumeCopyTemplateAsync(VolumeInfo volumeInfo, PrimaryDataStore primaryDataStore, TemplateInfo srcTemplateInfo, Host destHost, AsyncCallFuture<VolumeApiResult> future) {
    try {
        // Create a volume on managed storage.
        TemplateInfo destTemplateInfo = (TemplateInfo) primaryDataStore.create(srcTemplateInfo, false, volumeInfo.getDeployAsIsConfiguration());
        AsyncCallFuture<VolumeApiResult> createVolumeFuture = createVolumeAsync(volumeInfo, primaryDataStore);
        VolumeApiResult createVolumeResult = createVolumeFuture.get();
        if (createVolumeResult.isFailed()) {
            throw new CloudRuntimeException("Creation of a volume failed: " + createVolumeResult.getResult());
        }
        // Refresh the volume info from the DB.
        volumeInfo = volFactory.getVolume(volumeInfo.getId(), primaryDataStore);
        ManagedCreateBaseImageContext<CreateCmdResult> context = new ManagedCreateBaseImageContext<CreateCmdResult>(null, volumeInfo, primaryDataStore, srcTemplateInfo, future);
        AsyncCallbackDispatcher<VolumeServiceImpl, CopyCommandResult> caller = AsyncCallbackDispatcher.create(this);
        caller.setCallback(caller.getTarget().managedCopyBaseImageCallback(null, null)).setContext(context);
        Map<String, String> details = new HashMap<String, String>();
        details.put(PrimaryDataStore.MANAGED, Boolean.TRUE.toString());
        details.put(PrimaryDataStore.STORAGE_HOST, primaryDataStore.getHostAddress());
        details.put(PrimaryDataStore.STORAGE_PORT, String.valueOf(primaryDataStore.getPort()));
        // for managed storage, the storage repository (XenServer) or datastore (ESX) name is based off of the iScsiName property of a volume
        details.put(PrimaryDataStore.MANAGED_STORE_TARGET, volumeInfo.get_iScsiName());
        details.put(PrimaryDataStore.MANAGED_STORE_TARGET_ROOT_VOLUME, volumeInfo.getName());
        details.put(PrimaryDataStore.VOLUME_SIZE, String.valueOf(volumeInfo.getSize()));
        details.put(StorageManager.STORAGE_POOL_DISK_WAIT.toString(), String.valueOf(StorageManager.STORAGE_POOL_DISK_WAIT.valueIn(primaryDataStore.getId())));
        ChapInfo chapInfo = getChapInfo(volumeInfo, primaryDataStore);
        if (chapInfo != null) {
            details.put(PrimaryDataStore.CHAP_INITIATOR_USERNAME, chapInfo.getInitiatorUsername());
            details.put(PrimaryDataStore.CHAP_INITIATOR_SECRET, chapInfo.getInitiatorSecret());
            details.put(PrimaryDataStore.CHAP_TARGET_USERNAME, chapInfo.getTargetUsername());
            details.put(PrimaryDataStore.CHAP_TARGET_SECRET, chapInfo.getTargetSecret());
        }
        primaryDataStore.setDetails(details);
        grantAccess(volumeInfo, destHost, primaryDataStore);
        try {
            motionSrv.copyAsync(srcTemplateInfo, destTemplateInfo, destHost, caller);
        } finally {
            revokeAccess(volumeInfo, destHost, primaryDataStore);
        }
    } catch (Throwable t) {
        String errMsg = t.toString();
        volumeInfo.processEvent(Event.DestroyRequested);
        try {
            AsyncCallFuture<VolumeApiResult> expungeVolumeFuture = expungeVolumeAsync(volumeInfo);
            VolumeApiResult expungeVolumeResult = expungeVolumeFuture.get();
            if (expungeVolumeResult.isFailed()) {
                errMsg += " : Failed to expunge a volume that was created";
            }
        } catch (Exception ex) {
            errMsg += " : " + ex.getMessage();
        }
        VolumeApiResult result = new VolumeApiResult(volumeInfo);
        result.setResult(errMsg);
        future.complete(result);
    }
}
Also used : HashMap(java.util.HashMap) ChapInfo(org.apache.cloudstack.engine.subsystem.api.storage.ChapInfo) CreateCmdResult(org.apache.cloudstack.engine.subsystem.api.storage.CreateCmdResult) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) StorageAccessException(com.cloud.exception.StorageAccessException) ExecutionException(java.util.concurrent.ExecutionException) ResourceAllocationException(com.cloud.exception.ResourceAllocationException) AsyncCallFuture(org.apache.cloudstack.framework.async.AsyncCallFuture) TemplateInfo(org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) CopyCommandResult(org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)

Aggregations

CopyCommandResult (org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult)68 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)48 ExecutionException (java.util.concurrent.ExecutionException)27 CopyCmdAnswer (org.apache.cloudstack.storage.command.CopyCmdAnswer)21 VolumeInfo (org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo)20 ResourceAllocationException (com.cloud.exception.ResourceAllocationException)19 AgentUnavailableException (com.cloud.exception.AgentUnavailableException)17 OperationTimedoutException (com.cloud.exception.OperationTimedoutException)17 StorageAccessException (com.cloud.exception.StorageAccessException)17 DataStore (org.apache.cloudstack.engine.subsystem.api.storage.DataStore)16 DataObject (org.apache.cloudstack.engine.subsystem.api.storage.DataObject)14 AsyncCallFuture (org.apache.cloudstack.framework.async.AsyncCallFuture)14 HostVO (com.cloud.host.HostVO)12 Answer (com.cloud.agent.api.Answer)11 VMTemplateStoragePoolVO (com.cloud.storage.VMTemplateStoragePoolVO)11 HashMap (java.util.HashMap)10 EndPoint (org.apache.cloudstack.engine.subsystem.api.storage.EndPoint)9 MigrateWithStorageAnswer (com.cloud.agent.api.MigrateWithStorageAnswer)8 VMInstanceVO (com.cloud.vm.VMInstanceVO)8 StoragePoolVO (org.apache.cloudstack.storage.datastore.db.StoragePoolVO)8