Search in sources :

Example 56 with DataStoreTO

use of com.cloud.agent.api.to.DataStoreTO in project cloudstack by apache.

the class KVMStorageProcessor method backupSnapshot.

@Override
public Answer backupSnapshot(final CopyCommand cmd) {
    final DataTO srcData = cmd.getSrcTO();
    final DataTO destData = cmd.getDestTO();
    final SnapshotObjectTO snapshot = (SnapshotObjectTO) srcData;
    final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) snapshot.getDataStore();
    final SnapshotObjectTO destSnapshot = (SnapshotObjectTO) destData;
    final DataStoreTO imageStore = destData.getDataStore();
    if (!(imageStore instanceof NfsTO)) {
        return backupSnapshotForObjectStore(cmd);
    }
    final NfsTO nfsImageStore = (NfsTO) imageStore;
    final String secondaryStoragePoolUrl = nfsImageStore.getUrl();
    // NOTE: snapshot name is encoded in snapshot path
    final int index = snapshot.getPath().lastIndexOf("/");
    // -1 means the snapshot is created from existing vm snapshot
    final boolean isCreatedFromVmSnapshot = (index == -1) ? true : false;
    final String snapshotName = snapshot.getPath().substring(index + 1);
    String descName = snapshotName;
    final String volumePath = snapshot.getVolume().getPath();
    String snapshotDestPath = null;
    String snapshotRelPath = null;
    final String vmName = snapshot.getVmName();
    KVMStoragePool secondaryStoragePool = null;
    Connect conn = null;
    KVMPhysicalDisk snapshotDisk = null;
    KVMStoragePool primaryPool = null;
    try {
        conn = LibvirtConnection.getConnectionByVmName(vmName);
        secondaryStoragePool = storagePoolMgr.getStoragePoolByURI(secondaryStoragePoolUrl);
        final String ssPmountPath = secondaryStoragePool.getLocalPath();
        snapshotRelPath = destSnapshot.getPath();
        snapshotDestPath = ssPmountPath + File.separator + snapshotRelPath;
        snapshotDisk = storagePoolMgr.getPhysicalDisk(primaryStore.getPoolType(), primaryStore.getUuid(), volumePath);
        primaryPool = snapshotDisk.getPool();
        long size = 0;
        /**
             * Since Ceph version Dumpling (0.67.X) librbd / Qemu supports converting RBD
             * snapshots to RAW/QCOW2 files directly.
             *
             * This reduces the amount of time and storage it takes to back up a snapshot dramatically
             */
        if (primaryPool.getType() == StoragePoolType.RBD) {
            final String rbdSnapshot = snapshotDisk.getPath() + "@" + snapshotName;
            final String snapshotFile = snapshotDestPath + "/" + snapshotName;
            try {
                s_logger.debug("Attempting to backup RBD snapshot " + rbdSnapshot);
                final File snapDir = new File(snapshotDestPath);
                s_logger.debug("Attempting to create " + snapDir.getAbsolutePath() + " recursively for snapshot storage");
                FileUtils.forceMkdir(snapDir);
                final QemuImgFile srcFile = new QemuImgFile(KVMPhysicalDisk.RBDStringBuilder(primaryPool.getSourceHost(), primaryPool.getSourcePort(), primaryPool.getAuthUserName(), primaryPool.getAuthSecret(), rbdSnapshot));
                srcFile.setFormat(snapshotDisk.getFormat());
                final QemuImgFile destFile = new QemuImgFile(snapshotFile);
                destFile.setFormat(PhysicalDiskFormat.QCOW2);
                s_logger.debug("Backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile);
                final QemuImg q = new QemuImg(cmd.getWaitInMillSeconds());
                q.convert(srcFile, destFile);
                final File snapFile = new File(snapshotFile);
                if (snapFile.exists()) {
                    size = snapFile.length();
                }
                s_logger.debug("Finished backing up RBD snapshot " + rbdSnapshot + " to " + snapshotFile + " Snapshot size: " + size);
            } catch (final FileNotFoundException e) {
                s_logger.error("Failed to open " + snapshotDestPath + ". The error was: " + e.getMessage());
                return new CopyCmdAnswer(e.toString());
            } catch (final IOException e) {
                s_logger.error("Failed to create " + snapshotDestPath + ". The error was: " + e.getMessage());
                return new CopyCmdAnswer(e.toString());
            } catch (final QemuImgException e) {
                s_logger.error("Failed to backup the RBD snapshot from " + rbdSnapshot + " to " + snapshotFile + " the error was: " + e.getMessage());
                return new CopyCmdAnswer(e.toString());
            }
        } else {
            final Script command = new Script(_manageSnapshotPath, cmd.getWaitInMillSeconds(), s_logger);
            command.add("-b", snapshotDisk.getPath());
            command.add("-n", snapshotName);
            command.add("-p", snapshotDestPath);
            if (isCreatedFromVmSnapshot) {
                descName = UUID.randomUUID().toString();
            }
            command.add("-t", descName);
            final String result = command.execute();
            if (result != null) {
                s_logger.debug("Failed to backup snaptshot: " + result);
                return new CopyCmdAnswer(result);
            }
            final File snapFile = new File(snapshotDestPath + "/" + descName);
            if (snapFile.exists()) {
                size = snapFile.length();
            }
        }
        final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
        newSnapshot.setPath(snapshotRelPath + File.separator + descName);
        newSnapshot.setPhysicalSize(size);
        return new CopyCmdAnswer(newSnapshot);
    } catch (final LibvirtException e) {
        s_logger.debug("Failed to backup snapshot: ", e);
        return new CopyCmdAnswer(e.toString());
    } catch (final CloudRuntimeException e) {
        s_logger.debug("Failed to backup snapshot: ", e);
        return new CopyCmdAnswer(e.toString());
    } finally {
        if (isCreatedFromVmSnapshot) {
            s_logger.debug("Ignoring removal of vm snapshot on primary as this snapshot is created from vm snapshot");
        } else {
            try {
                /* Delete the snapshot on primary */
                DomainInfo.DomainState state = null;
                Domain vm = null;
                if (vmName != null) {
                    try {
                        vm = resource.getDomain(conn, vmName);
                        state = vm.getInfo().state;
                    } catch (final LibvirtException e) {
                        s_logger.trace("Ignoring libvirt error.", e);
                    }
                }
                final KVMStoragePool primaryStorage = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
                if (state == DomainInfo.DomainState.VIR_DOMAIN_RUNNING && !primaryStorage.isExternalSnapshot()) {
                    final DomainSnapshot snap = vm.snapshotLookupByName(snapshotName);
                    snap.delete(0);
                    /*
                         * libvirt on RHEL6 doesn't handle resume event emitted from
                         * qemu
                         */
                    vm = resource.getDomain(conn, vmName);
                    state = vm.getInfo().state;
                    if (state == DomainInfo.DomainState.VIR_DOMAIN_PAUSED) {
                        vm.resume();
                    }
                } else {
                    if (primaryPool.getType() != StoragePoolType.RBD) {
                        final Script command = new Script(_manageSnapshotPath, _cmdsTimeout, s_logger);
                        command.add("-d", snapshotDisk.getPath());
                        command.add("-n", snapshotName);
                        final String result = command.execute();
                        if (result != null) {
                            s_logger.debug("Failed to delete snapshot on primary: " + result);
                        // return new CopyCmdAnswer("Failed to backup snapshot: " + result);
                        }
                    }
                }
            } catch (final Exception ex) {
                s_logger.debug("Failed to delete snapshots on primary", ex);
            }
        }
        try {
            if (secondaryStoragePool != null) {
                secondaryStoragePool.delete();
            }
        } catch (final Exception ex) {
            s_logger.debug("Failed to delete secondary storage", ex);
        }
    }
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) LibvirtException(org.libvirt.LibvirtException) FileNotFoundException(java.io.FileNotFoundException) DataTO(com.cloud.agent.api.to.DataTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) QemuImgException(org.apache.cloudstack.utils.qemu.QemuImgException) DomainInfo(org.libvirt.DomainInfo) Script(com.cloud.utils.script.Script) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) Connect(org.libvirt.Connect) DomainSnapshot(org.libvirt.DomainSnapshot) IOException(java.io.IOException) NfsTO(com.cloud.agent.api.to.NfsTO) URISyntaxException(java.net.URISyntaxException) LibvirtException(org.libvirt.LibvirtException) RbdException(com.ceph.rbd.RbdException) QemuImgException(org.apache.cloudstack.utils.qemu.QemuImgException) FileNotFoundException(java.io.FileNotFoundException) InternalErrorException(com.cloud.exception.InternalErrorException) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) RadosException(com.ceph.rados.exceptions.RadosException) IOException(java.io.IOException) QemuImg(org.apache.cloudstack.utils.qemu.QemuImg) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) QemuImgFile(org.apache.cloudstack.utils.qemu.QemuImgFile) Domain(org.libvirt.Domain) QemuImgFile(org.apache.cloudstack.utils.qemu.QemuImgFile) S3Utils.putFile(com.cloud.utils.storage.S3.S3Utils.putFile) File(java.io.File) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 57 with DataStoreTO

use of com.cloud.agent.api.to.DataStoreTO in project cloudstack by apache.

the class KVMStorageProcessor method copyToObjectStore.

protected Answer copyToObjectStore(final CopyCommand cmd) {
    final DataTO srcData = cmd.getSrcTO();
    final DataTO destData = cmd.getDestTO();
    final DataStoreTO imageStore = destData.getDataStore();
    final NfsTO srcStore = (NfsTO) srcData.getDataStore();
    final String srcPath = srcData.getPath();
    final int index = srcPath.lastIndexOf(File.separator);
    final String srcSnapshotDir = srcPath.substring(0, index);
    final String srcFileName = srcPath.substring(index + 1);
    KVMStoragePool srcStorePool = null;
    File srcFile = null;
    try {
        srcStorePool = storagePoolMgr.getStoragePoolByURI(srcStore.getUrl() + File.separator + srcSnapshotDir);
        if (srcStorePool == null) {
            return new CopyCmdAnswer("Can't get store:" + srcStore.getUrl());
        }
        srcFile = new File(srcStorePool.getLocalPath() + File.separator + srcFileName);
        if (!srcFile.exists()) {
            return new CopyCmdAnswer("Can't find src file: " + srcPath);
        }
        String destPath = null;
        if (imageStore instanceof S3TO) {
            destPath = copyToS3(srcFile, (S3TO) imageStore, destData.getPath());
        } else {
            return new CopyCmdAnswer("Unsupported protocol");
        }
        final SnapshotObjectTO newSnapshot = new SnapshotObjectTO();
        newSnapshot.setPath(destPath);
        return new CopyCmdAnswer(newSnapshot);
    } catch (final Exception e) {
        s_logger.error("failed to upload" + srcPath, e);
        return new CopyCmdAnswer("failed to upload" + srcPath + e.toString());
    } finally {
        try {
            if (srcFile != null) {
                srcFile.delete();
            }
            if (srcStorePool != null) {
                srcStorePool.delete();
            }
        } catch (final Exception e) {
            s_logger.debug("Failed to clean up:", e);
        }
    }
}
Also used : SnapshotObjectTO(org.apache.cloudstack.storage.to.SnapshotObjectTO) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) DataTO(com.cloud.agent.api.to.DataTO) NfsTO(com.cloud.agent.api.to.NfsTO) QemuImgFile(org.apache.cloudstack.utils.qemu.QemuImgFile) S3Utils.putFile(com.cloud.utils.storage.S3.S3Utils.putFile) File(java.io.File) S3TO(com.cloud.agent.api.to.S3TO) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) URISyntaxException(java.net.URISyntaxException) LibvirtException(org.libvirt.LibvirtException) RbdException(com.ceph.rbd.RbdException) QemuImgException(org.apache.cloudstack.utils.qemu.QemuImgException) FileNotFoundException(java.io.FileNotFoundException) InternalErrorException(com.cloud.exception.InternalErrorException) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) RadosException(com.ceph.rados.exceptions.RadosException) IOException(java.io.IOException)

Example 58 with DataStoreTO

use of com.cloud.agent.api.to.DataStoreTO in project cloudstack by apache.

the class KVMStorageProcessor method dettachIso.

@Override
public Answer dettachIso(final DettachCommand cmd) {
    final DiskTO disk = cmd.getDisk();
    final TemplateObjectTO isoTO = (TemplateObjectTO) disk.getData();
    final DataStoreTO store = isoTO.getDataStore();
    if (!(store instanceof NfsTO)) {
        return new AttachAnswer("unsupported protocol");
    }
    final NfsTO nfsStore = (NfsTO) store;
    try {
        final Connect conn = LibvirtConnection.getConnectionByVmName(cmd.getVmName());
        attachOrDetachISO(conn, cmd.getVmName(), nfsStore.getUrl() + File.separator + isoTO.getPath(), false);
    } catch (final LibvirtException e) {
        return new Answer(cmd, false, e.toString());
    } catch (final URISyntaxException e) {
        return new Answer(cmd, false, e.toString());
    } catch (final InternalErrorException e) {
        return new Answer(cmd, false, e.toString());
    }
    return new Answer(cmd);
}
Also used : CreateObjectAnswer(org.apache.cloudstack.storage.command.CreateObjectAnswer) ResignatureAnswer(org.apache.cloudstack.storage.command.ResignatureAnswer) Answer(com.cloud.agent.api.Answer) PrimaryStorageDownloadAnswer(com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer) DettachAnswer(org.apache.cloudstack.storage.command.DettachAnswer) SnapshotAndCopyAnswer(org.apache.cloudstack.storage.command.SnapshotAndCopyAnswer) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) AttachAnswer(org.apache.cloudstack.storage.command.AttachAnswer) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) LibvirtException(org.libvirt.LibvirtException) Connect(org.libvirt.Connect) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) URISyntaxException(java.net.URISyntaxException) InternalErrorException(com.cloud.exception.InternalErrorException) NfsTO(com.cloud.agent.api.to.NfsTO) DiskTO(com.cloud.agent.api.to.DiskTO) AttachAnswer(org.apache.cloudstack.storage.command.AttachAnswer)

Example 59 with DataStoreTO

use of com.cloud.agent.api.to.DataStoreTO in project cloudstack by apache.

the class KVMStorageProcessor method copyTemplateToPrimaryStorage.

@Override
public Answer copyTemplateToPrimaryStorage(final CopyCommand cmd) {
    final DataTO srcData = cmd.getSrcTO();
    final DataTO destData = cmd.getDestTO();
    final TemplateObjectTO template = (TemplateObjectTO) srcData;
    final DataStoreTO imageStore = template.getDataStore();
    final PrimaryDataStoreTO primaryStore = (PrimaryDataStoreTO) destData.getDataStore();
    if (!(imageStore instanceof NfsTO)) {
        return new CopyCmdAnswer("unsupported protocol");
    }
    final NfsTO nfsImageStore = (NfsTO) imageStore;
    final String tmplturl = nfsImageStore.getUrl() + File.separator + template.getPath();
    final int index = tmplturl.lastIndexOf("/");
    final String mountpoint = tmplturl.substring(0, index);
    String tmpltname = null;
    if (index < tmplturl.length() - 1) {
        tmpltname = tmplturl.substring(index + 1);
    }
    KVMPhysicalDisk tmplVol = null;
    KVMStoragePool secondaryPool = null;
    try {
        secondaryPool = storagePoolMgr.getStoragePoolByURI(mountpoint);
        /* Get template vol */
        if (tmpltname == null) {
            secondaryPool.refresh();
            final List<KVMPhysicalDisk> disks = secondaryPool.listPhysicalDisks();
            if (disks == null || disks.isEmpty()) {
                return new PrimaryStorageDownloadAnswer("Failed to get volumes from pool: " + secondaryPool.getUuid());
            }
            for (final KVMPhysicalDisk disk : disks) {
                if (disk.getName().endsWith("qcow2")) {
                    tmplVol = disk;
                    break;
                }
            }
        } else {
            tmplVol = secondaryPool.getPhysicalDisk(tmpltname);
        }
        if (tmplVol == null) {
            return new PrimaryStorageDownloadAnswer("Failed to get template from pool: " + secondaryPool.getUuid());
        }
        /* Copy volume to primary storage */
        s_logger.debug("Copying template to primary storage, template format is " + tmplVol.getFormat());
        final KVMStoragePool primaryPool = storagePoolMgr.getStoragePool(primaryStore.getPoolType(), primaryStore.getUuid());
        KVMPhysicalDisk primaryVol = null;
        if (destData instanceof VolumeObjectTO) {
            final VolumeObjectTO volume = (VolumeObjectTO) destData;
            // pass along volume's target size if it's bigger than template's size, for storage types that copy template rather than cloning on deploy
            if (volume.getSize() != null && volume.getSize() > tmplVol.getVirtualSize()) {
                s_logger.debug("Using configured size of " + volume.getSize());
                tmplVol.setSize(volume.getSize());
                tmplVol.setVirtualSize(volume.getSize());
            } else {
                s_logger.debug("Using template's size of " + tmplVol.getVirtualSize());
            }
            primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, volume.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
        } else if (destData instanceof TemplateObjectTO) {
            final TemplateObjectTO destTempl = (TemplateObjectTO) destData;
            primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, destTempl.getUuid(), primaryPool, cmd.getWaitInMillSeconds());
        } else {
            primaryVol = storagePoolMgr.copyPhysicalDisk(tmplVol, UUID.randomUUID().toString(), primaryPool, cmd.getWaitInMillSeconds());
        }
        DataTO data = null;
        /**
             * Force the ImageFormat for RBD templates to RAW
             *
             */
        if (destData.getObjectType() == DataObjectType.TEMPLATE) {
            final TemplateObjectTO newTemplate = new TemplateObjectTO();
            newTemplate.setPath(primaryVol.getName());
            newTemplate.setSize(primaryVol.getSize());
            if (primaryPool.getType() == StoragePoolType.RBD) {
                newTemplate.setFormat(ImageFormat.RAW);
            } else {
                newTemplate.setFormat(ImageFormat.QCOW2);
            }
            data = newTemplate;
        } else if (destData.getObjectType() == DataObjectType.VOLUME) {
            final VolumeObjectTO volumeObjectTO = new VolumeObjectTO();
            volumeObjectTO.setPath(primaryVol.getName());
            volumeObjectTO.setSize(primaryVol.getSize());
            if (primaryVol.getFormat() == PhysicalDiskFormat.RAW) {
                volumeObjectTO.setFormat(ImageFormat.RAW);
            } else if (primaryVol.getFormat() == PhysicalDiskFormat.QCOW2) {
                volumeObjectTO.setFormat(ImageFormat.QCOW2);
            }
            data = volumeObjectTO;
        }
        return new CopyCmdAnswer(data);
    } catch (final CloudRuntimeException e) {
        return new CopyCmdAnswer(e.toString());
    } finally {
        try {
            if (secondaryPool != null) {
                secondaryPool.delete();
            }
        } catch (final Exception e) {
            s_logger.debug("Failed to clean up secondary storage", e);
        }
    }
}
Also used : PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) NfsTO(com.cloud.agent.api.to.NfsTO) URISyntaxException(java.net.URISyntaxException) LibvirtException(org.libvirt.LibvirtException) RbdException(com.ceph.rbd.RbdException) QemuImgException(org.apache.cloudstack.utils.qemu.QemuImgException) FileNotFoundException(java.io.FileNotFoundException) InternalErrorException(com.cloud.exception.InternalErrorException) ConfigurationException(javax.naming.ConfigurationException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) RadosException(com.ceph.rados.exceptions.RadosException) IOException(java.io.IOException) PrimaryStorageDownloadAnswer(com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer) DataTO(com.cloud.agent.api.to.DataTO) PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer)

Example 60 with DataStoreTO

use of com.cloud.agent.api.to.DataStoreTO in project cloudstack by apache.

the class VmwareStorageProcessor method cloneVolumeFromBaseTemplate.

@Override
public Answer cloneVolumeFromBaseTemplate(CopyCommand cmd) {
    DataTO srcData = cmd.getSrcTO();
    TemplateObjectTO template = (TemplateObjectTO) srcData;
    DataTO destData = cmd.getDestTO();
    VolumeObjectTO volume = (VolumeObjectTO) destData;
    DataStoreTO primaryStore = volume.getDataStore();
    DataStoreTO srcStore = template.getDataStore();
    try {
        VmwareContext context = hostService.getServiceContext(null);
        VmwareHypervisorHost hyperHost = hostService.getHyperHost(context, null);
        DatacenterMO dcMo = new DatacenterMO(context, hyperHost.getHyperHostDatacenter());
        VirtualMachineMO vmMo = null;
        ManagedObjectReference morDatastore = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(hyperHost, primaryStore.getUuid());
        if (morDatastore == null) {
            throw new Exception("Unable to find datastore in vSphere");
        }
        DatastoreMO dsMo = new DatastoreMO(context, morDatastore);
        String vmdkName = volume.getName();
        String vmdkFileBaseName = null;
        if (srcStore == null) {
            // create a root volume for blank VM (created from ISO)
            String dummyVmName = hostService.getWorkerName(context, cmd, 0);
            try {
                vmMo = HypervisorHostHelper.createWorkerVM(hyperHost, dsMo, dummyVmName);
                if (vmMo == null) {
                    throw new Exception("Unable to create a dummy VM for volume creation");
                }
                vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
                // we only use the first file in the pair, linked or not will not matter
                String[] vmdkFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, null, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, true);
                String volumeDatastorePath = vmdkFilePair[0];
                synchronized (this) {
                    s_logger.info("Delete file if exists in datastore to clear the way for creating the volume. file: " + volumeDatastorePath);
                    VmwareStorageLayoutHelper.deleteVolumeVmdkFiles(dsMo, vmdkName, dcMo);
                    vmMo.createDisk(volumeDatastorePath, (int) (volume.getSize() / (1024L * 1024L)), morDatastore, -1);
                    vmMo.detachDisk(volumeDatastorePath, false);
                }
            } finally {
                s_logger.info("Destroy dummy VM after volume creation");
                if (vmMo != null) {
                    s_logger.warn("Unable to destroy a null VM ManagedObjectReference");
                    vmMo.detachAllDisks();
                    vmMo.destroy();
                }
            }
        } else {
            String templatePath = template.getPath();
            VirtualMachineMO vmTemplate = VmwareHelper.pickOneVmOnRunningHost(dcMo.findVmByNameAndLabel(templatePath), true);
            if (vmTemplate == null) {
                s_logger.warn("Template host in vSphere is not in connected state, request template reload");
                return new CopyCmdAnswer("Template host in vSphere is not in connected state, request template reload");
            }
            ManagedObjectReference morPool = hyperHost.getHyperHostOwnerResourcePool();
            ManagedObjectReference morCluster = hyperHost.getHyperHostCluster();
            if (!_fullCloneFlag) {
                createVMLinkedClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool);
            } else {
                createVMFullClone(vmTemplate, dcMo, dsMo, vmdkName, morDatastore, morPool);
            }
            vmMo = new ClusterMO(context, morCluster).findVmOnHyperHost(vmdkName);
            assert (vmMo != null);
            // TO-DO: Support for base template containing multiple disks
            vmdkFileBaseName = vmMo.getVmdkFileBaseNames().get(0);
            s_logger.info("Move volume out of volume-wrapper VM ");
            String[] vmwareLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.VMWARE, !_fullCloneFlag);
            String[] legacyCloudStackLayoutFilePair = VmwareStorageLayoutHelper.getVmdkFilePairDatastorePath(dsMo, vmdkName, vmdkFileBaseName, VmwareStorageLayoutType.CLOUDSTACK_LEGACY, !_fullCloneFlag);
            dsMo.moveDatastoreFile(vmwareLayoutFilePair[0], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[0], dcMo.getMor(), true);
            dsMo.moveDatastoreFile(vmwareLayoutFilePair[1], dcMo.getMor(), dsMo.getMor(), legacyCloudStackLayoutFilePair[1], dcMo.getMor(), true);
            s_logger.info("detach disks from volume-wrapper VM " + vmdkName);
            vmMo.detachAllDisks();
            s_logger.info("destroy volume-wrapper VM " + vmdkName);
            vmMo.destroy();
            String srcFile = dsMo.getDatastorePath(vmdkName, true);
            dsMo.deleteFile(srcFile, dcMo.getMor(), true);
        }
        // restoreVM - move the new ROOT disk into corresponding VM folder
        VirtualMachineMO restoreVmMo = dcMo.findVm(volume.getVmName());
        if (restoreVmMo != null) {
            // VM folder name in datastore will be VM's name in vCenter.
            String vmNameInVcenter = restoreVmMo.getName();
            if (dsMo.folderExists(String.format("[%s]", dsMo.getName()), vmNameInVcenter)) {
                VmwareStorageLayoutHelper.syncVolumeToVmDefaultFolder(dcMo, vmNameInVcenter, dsMo, vmdkFileBaseName);
            }
        }
        VolumeObjectTO newVol = new VolumeObjectTO();
        newVol.setPath(vmdkFileBaseName);
        newVol.setSize(volume.getSize());
        return new CopyCmdAnswer(newVol);
    } catch (Throwable e) {
        if (e instanceof RemoteException) {
            s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
            hostService.invalidateServiceContext(null);
        }
        String msg = "clone volume from base image failed due to " + VmwareHelper.getExceptionMessage(e);
        s_logger.error(msg, e);
        return new CopyCmdAnswer(e.toString());
    }
}
Also used : PrimaryDataStoreTO(org.apache.cloudstack.storage.to.PrimaryDataStoreTO) DataStoreTO(com.cloud.agent.api.to.DataStoreTO) VirtualMachineMO(com.cloud.hypervisor.vmware.mo.VirtualMachineMO) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) ClusterMO(com.cloud.hypervisor.vmware.mo.ClusterMO) RemoteException(java.rmi.RemoteException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) DatastoreMO(com.cloud.hypervisor.vmware.mo.DatastoreMO) VmwareContext(com.cloud.hypervisor.vmware.util.VmwareContext) DataTO(com.cloud.agent.api.to.DataTO) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) TemplateObjectTO(org.apache.cloudstack.storage.to.TemplateObjectTO) RemoteException(java.rmi.RemoteException) CopyCmdAnswer(org.apache.cloudstack.storage.command.CopyCmdAnswer) DatacenterMO(com.cloud.hypervisor.vmware.mo.DatacenterMO) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Aggregations

DataStoreTO (com.cloud.agent.api.to.DataStoreTO)91 NfsTO (com.cloud.agent.api.to.NfsTO)66 CopyCmdAnswer (org.apache.cloudstack.storage.command.CopyCmdAnswer)54 PrimaryDataStoreTO (org.apache.cloudstack.storage.to.PrimaryDataStoreTO)50 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)47 DataTO (com.cloud.agent.api.to.DataTO)46 VolumeObjectTO (org.apache.cloudstack.storage.to.VolumeObjectTO)36 InternalErrorException (com.cloud.exception.InternalErrorException)30 TemplateObjectTO (org.apache.cloudstack.storage.to.TemplateObjectTO)28 Answer (com.cloud.agent.api.Answer)26 SnapshotObjectTO (org.apache.cloudstack.storage.to.SnapshotObjectTO)20 UnsupportedEncodingException (java.io.UnsupportedEncodingException)19 IOException (java.io.IOException)17 S3TO (com.cloud.agent.api.to.S3TO)16 ConfigurationException (javax.naming.ConfigurationException)16 XmlRpcException (org.apache.xmlrpc.XmlRpcException)16 XenAPIException (com.xensource.xenapi.Types.XenAPIException)15 RemoteException (java.rmi.RemoteException)15 SwiftTO (com.cloud.agent.api.to.SwiftTO)14 ManagedObjectReference (com.vmware.vim25.ManagedObjectReference)14