Search in sources :

Example 1 with VirtualMachineRelocateSpec

use of com.vmware.vim25.VirtualMachineRelocateSpec in project CloudStack-archive by CloudStack-extras.

the class VirtualMachineMO method relocate.

public boolean relocate(ManagedObjectReference morTargetHost) throws Exception {
    VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
    relocateSpec.setHost(morTargetHost);
    ManagedObjectReference morTask = _context.getService().relocateVM_Task(_mor, relocateSpec, null);
    String result = _context.getServiceUtil().waitForTask(morTask);
    if (result.equals("sucess")) {
        _context.waitForTaskProgressDone(morTask);
        return true;
    } else {
        s_logger.error("VMware relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
    }
    return false;
}
Also used : VirtualMachineRelocateSpec(com.vmware.vim25.VirtualMachineRelocateSpec) ArrayOfManagedObjectReference(com.vmware.vim25.ArrayOfManagedObjectReference) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 2 with VirtualMachineRelocateSpec

use of com.vmware.vim25.VirtualMachineRelocateSpec in project cloudstack by apache.

the class VmwareResource method execute.

protected Answer execute(MigrateWithStorageCommand cmd) {
    if (s_logger.isInfoEnabled()) {
        s_logger.info("Executing resource MigrateWithStorageCommand: " + _gson.toJson(cmd));
    }
    VirtualMachineTO vmTo = cmd.getVirtualMachine();
    String vmName = vmTo.getName();
    VmwareHypervisorHost srcHyperHost = null;
    VmwareHypervisorHost tgtHyperHost = null;
    VirtualMachineMO vmMo = null;
    ManagedObjectReference morDsAtTarget = null;
    ManagedObjectReference morDsAtSource = null;
    ManagedObjectReference morDc = null;
    ManagedObjectReference morDcOfTargetHost = null;
    ManagedObjectReference morTgtHost = new ManagedObjectReference();
    ManagedObjectReference morTgtDatastore = new ManagedObjectReference();
    VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
    List<VirtualMachineRelocateSpecDiskLocator> diskLocators = new ArrayList<VirtualMachineRelocateSpecDiskLocator>();
    VirtualMachineRelocateSpecDiskLocator diskLocator = null;
    String tgtDsName = "";
    String tgtDsHost;
    String tgtDsPath;
    int tgtDsPort;
    VolumeTO volume;
    StorageFilerTO filerTo;
    Set<String> mountedDatastoresAtSource = new HashSet<String>();
    List<VolumeObjectTO> volumeToList = new ArrayList<VolumeObjectTO>();
    Map<Long, Integer> volumeDeviceKey = new HashMap<Long, Integer>();
    List<Pair<VolumeTO, StorageFilerTO>> volToFiler = cmd.getVolumeToFilerAsList();
    String tgtHost = cmd.getTargetHost();
    String tgtHostMorInfo = tgtHost.split("@")[0];
    morTgtHost.setType(tgtHostMorInfo.split(":")[0]);
    morTgtHost.setValue(tgtHostMorInfo.split(":")[1]);
    try {
        srcHyperHost = getHyperHost(getServiceContext());
        tgtHyperHost = new HostMO(getServiceContext(), morTgtHost);
        morDc = srcHyperHost.getHyperHostDatacenter();
        morDcOfTargetHost = tgtHyperHost.getHyperHostDatacenter();
        if (!morDc.getValue().equalsIgnoreCase(morDcOfTargetHost.getValue())) {
            String msg = "Source host & target host are in different datacentesr";
            throw new CloudRuntimeException(msg);
        }
        VmwareManager mgr = tgtHyperHost.getContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
        String srcHostApiVersion = ((HostMO) srcHyperHost).getHostAboutInfo().getApiVersion();
        // find VM through datacenter (VM is not at the target host yet)
        vmMo = srcHyperHost.findVmOnPeerHyperHost(vmName);
        if (vmMo == null) {
            String msg = "VM " + vmName + " does not exist in VMware datacenter " + morDc.getValue();
            s_logger.error(msg);
            throw new Exception(msg);
        }
        vmName = vmMo.getName();
        // Specify destination datastore location for each volume
        for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
            volume = entry.first();
            filerTo = entry.second();
            s_logger.debug("Preparing spec for volume : " + volume.getName());
            morDsAtTarget = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(tgtHyperHost, filerTo.getUuid());
            morDsAtSource = HypervisorHostHelper.findDatastoreWithBackwardsCompatibility(srcHyperHost, filerTo.getUuid());
            if (morDsAtTarget == null) {
                String msg = "Unable to find the target datastore: " + filerTo.getUuid() + " on target host: " + tgtHyperHost.getHyperHostName() + " to execute MigrateWithStorageCommand";
                s_logger.error(msg);
                throw new Exception(msg);
            }
            morTgtDatastore = morDsAtTarget;
            // So since only the datastore will be changed first, ensure the target datastore is mounted on source host.
            if (srcHostApiVersion.compareTo("5.1") < 0) {
                tgtDsName = filerTo.getUuid().replace("-", "");
                tgtDsHost = filerTo.getHost();
                tgtDsPath = filerTo.getPath();
                tgtDsPort = filerTo.getPort();
                // If datastore is NFS and target datastore is not already mounted on source host then mount the datastore.
                if (filerTo.getType().equals(StoragePoolType.NetworkFilesystem)) {
                    if (morDsAtSource == null) {
                        morDsAtSource = srcHyperHost.mountDatastore(false, tgtDsHost, tgtDsPort, tgtDsPath, tgtDsName);
                        if (morDsAtSource == null) {
                            throw new Exception("Unable to mount NFS datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
                        }
                        mountedDatastoresAtSource.add(tgtDsName);
                        s_logger.debug("Mounted datastore " + tgtDsHost + ":/" + tgtDsPath + " on " + _hostName);
                    }
                }
                // If datastore is VMFS and target datastore is not mounted or accessible to source host then fail migration.
                if (filerTo.getType().equals(StoragePoolType.VMFS)) {
                    if (morDsAtSource == null) {
                        s_logger.warn("If host version is below 5.1, then target VMFS datastore(s) need to manually mounted on source host for a successful live storage migration.");
                        throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not mounted on source host: " + _hostName);
                    }
                    DatastoreMO dsAtSourceMo = new DatastoreMO(getServiceContext(), morDsAtSource);
                    String srcHostValue = srcHyperHost.getMor().getValue();
                    if (!dsAtSourceMo.isAccessibleToHost(srcHostValue)) {
                        s_logger.warn("If host version is below 5.1, then target VMFS datastore(s) need to accessible to source host for a successful live storage migration.");
                        throw new Exception("Target VMFS datastore: " + tgtDsPath + " is not accessible on source host: " + _hostName);
                    }
                }
                morTgtDatastore = morDsAtSource;
            }
            if (volume.getType() == Volume.Type.ROOT) {
                relocateSpec.setDatastore(morTgtDatastore);
            }
            diskLocator = new VirtualMachineRelocateSpecDiskLocator();
            diskLocator.setDatastore(morDsAtSource);
            Pair<VirtualDisk, String> diskInfo = getVirtualDiskInfo(vmMo, volume.getPath() + ".vmdk");
            String vmdkAbsFile = getAbsoluteVmdkFile(diskInfo.first());
            if (vmdkAbsFile != null && !vmdkAbsFile.isEmpty()) {
                vmMo.updateAdapterTypeIfRequired(vmdkAbsFile);
            }
            int diskId = diskInfo.first().getKey();
            diskLocator.setDiskId(diskId);
            diskLocators.add(diskLocator);
            volumeDeviceKey.put(volume.getId(), diskId);
        }
        // If a target datastore is provided for the VM, then by default all volumes associated with the VM will be migrated to that target datastore.
        // Hence set the existing datastore as target datastore for volumes that are not to be migrated.
        List<Pair<Integer, ManagedObjectReference>> diskDatastores = vmMo.getAllDiskDatastores();
        for (Pair<Integer, ManagedObjectReference> diskDatastore : diskDatastores) {
            if (!volumeDeviceKey.containsValue(diskDatastore.first().intValue())) {
                diskLocator = new VirtualMachineRelocateSpecDiskLocator();
                diskLocator.setDiskId(diskDatastore.first().intValue());
                diskLocator.setDatastore(diskDatastore.second());
                diskLocators.add(diskLocator);
            }
        }
        relocateSpec.getDisk().addAll(diskLocators);
        // Prepare network at target before migration
        NicTO[] nics = vmTo.getNics();
        for (NicTO nic : nics) {
            // prepare network on the host
            prepareNetworkFromNicInfo(new HostMO(getServiceContext(), morTgtHost), nic, false, vmTo.getType());
        }
        // Ensure secondary storage mounted on target host
        Pair<String, Long> secStoreUrlAndId = mgr.getSecondaryStorageStoreUrlAndId(Long.parseLong(_dcId));
        String secStoreUrl = secStoreUrlAndId.first();
        Long secStoreId = secStoreUrlAndId.second();
        if (secStoreUrl == null) {
            String msg = "secondary storage for dc " + _dcId + " is not ready yet?";
            throw new Exception(msg);
        }
        mgr.prepareSecondaryStorageStore(secStoreUrl, secStoreId);
        ManagedObjectReference morSecDs = prepareSecondaryDatastoreOnSpecificHost(secStoreUrl, tgtHyperHost);
        if (morSecDs == null) {
            String msg = "Failed to prepare secondary storage on host, secondary store url: " + secStoreUrl;
            throw new Exception(msg);
        }
        if (srcHostApiVersion.compareTo("5.1") < 0) {
            // Migrate VM's volumes to target datastore(s).
            if (!vmMo.changeDatastore(relocateSpec)) {
                throw new Exception("Change datastore operation failed during storage migration");
            } else {
                s_logger.debug("Successfully migrated storage of VM " + vmName + " to target datastore(s)");
            }
            // Migrate VM to target host.
            ManagedObjectReference morPool = tgtHyperHost.getHyperHostOwnerResourcePool();
            if (!vmMo.migrate(morPool, tgtHyperHost.getMor())) {
                throw new Exception("VM migration to target host failed during storage migration");
            } else {
                s_logger.debug("Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName());
            }
        } else {
            // Simultaneously migrate VM's volumes to target datastore and VM to target host.
            relocateSpec.setHost(tgtHyperHost.getMor());
            relocateSpec.setPool(tgtHyperHost.getHyperHostOwnerResourcePool());
            if (!vmMo.changeDatastore(relocateSpec)) {
                throw new Exception("Change datastore operation failed during storage migration");
            } else {
                s_logger.debug("Successfully migrated VM " + vmName + " from " + _hostName + " to " + tgtHyperHost.getHyperHostName() + " and its storage to target datastore(s)");
            }
        }
        // In case of a linked clone VM, if VM's disks are not consolidated, further VM operations such as volume snapshot, VM snapshot etc. will result in DB inconsistencies.
        if (!vmMo.consolidateVmDisks()) {
            s_logger.warn("VM disk consolidation failed after storage migration. Yet proceeding with VM migration.");
        } else {
            s_logger.debug("Successfully consolidated disks of VM " + vmName + ".");
        }
        // Update and return volume path and chain info for every disk because that could have changed after migration
        VirtualMachineDiskInfoBuilder diskInfoBuilder = vmMo.getDiskInfoBuilder();
        for (Pair<VolumeTO, StorageFilerTO> entry : volToFiler) {
            volume = entry.first();
            long volumeId = volume.getId();
            VirtualDisk[] disks = vmMo.getAllDiskDevice();
            for (VirtualDisk disk : disks) {
                if (volumeDeviceKey.get(volumeId) == disk.getKey()) {
                    VolumeObjectTO newVol = new VolumeObjectTO();
                    String newPath = vmMo.getVmdkFileBaseName(disk);
                    String poolName = entry.second().getUuid().replace("-", "");
                    VirtualMachineDiskInfo diskInfo = diskInfoBuilder.getDiskInfoByBackingFileBaseName(newPath, poolName);
                    newVol.setId(volumeId);
                    newVol.setPath(newPath);
                    newVol.setChainInfo(_gson.toJson(diskInfo));
                    volumeToList.add(newVol);
                    break;
                }
            }
        }
        return new MigrateWithStorageAnswer(cmd, volumeToList);
    } catch (Throwable e) {
        if (e instanceof RemoteException) {
            s_logger.warn("Encountered remote exception at vCenter, invalidating VMware session context");
            invalidateServiceContext();
        }
        String msg = "MigrationCommand failed due to " + VmwareHelper.getExceptionMessage(e);
        s_logger.warn(msg, e);
        return new MigrateWithStorageAnswer(cmd, (Exception) e);
    } finally {
        // Cleanup datastores mounted on source host
        for (String mountedDatastore : mountedDatastoresAtSource) {
            s_logger.debug("Attempting to unmount datastore " + mountedDatastore + " at " + _hostName);
            try {
                srcHyperHost.unmountDatastore(mountedDatastore);
            } catch (Exception unmountEx) {
                s_logger.debug("Failed to unmount datastore " + mountedDatastore + " at " + _hostName + ". Seems the datastore is still being used by " + _hostName + ". Please unmount manually to cleanup.");
            }
            s_logger.debug("Successfully unmounted datastore " + mountedDatastore + " at " + _hostName);
        }
    }
}
Also used : HashMap(java.util.HashMap) HostMO(com.cloud.hypervisor.vmware.mo.HostMO) ArrayList(java.util.ArrayList) StorageFilerTO(com.cloud.agent.api.to.StorageFilerTO) VirtualMachineTO(com.cloud.agent.api.to.VirtualMachineTO) VolumeTO(com.cloud.agent.api.to.VolumeTO) VirtualMachineRelocateSpec(com.vmware.vim25.VirtualMachineRelocateSpec) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) VirtualMachineDiskInfo(org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo) VolumeObjectTO(org.apache.cloudstack.storage.to.VolumeObjectTO) HashSet(java.util.HashSet) Pair(com.cloud.utils.Pair) NicTO(com.cloud.agent.api.to.NicTO) MigrateWithStorageAnswer(com.cloud.agent.api.MigrateWithStorageAnswer) VmwareManager(com.cloud.hypervisor.vmware.manager.VmwareManager) VirtualMachineMO(com.cloud.hypervisor.vmware.mo.VirtualMachineMO) VirtualMachineDiskInfoBuilder(com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder) VmwareHypervisorHost(com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost) ConnectException(java.net.ConnectException) IOException(java.io.IOException) RemoteException(java.rmi.RemoteException) InternalErrorException(com.cloud.exception.InternalErrorException) CloudException(com.cloud.exception.CloudException) CloudRuntimeException(com.cloud.utils.exception.CloudRuntimeException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ConfigurationException(javax.naming.ConfigurationException) DatastoreMO(com.cloud.hypervisor.vmware.mo.DatastoreMO) VirtualDisk(com.vmware.vim25.VirtualDisk) RemoteException(java.rmi.RemoteException) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference) VirtualMachineRelocateSpecDiskLocator(com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator)

Example 3 with VirtualMachineRelocateSpec

use of com.vmware.vim25.VirtualMachineRelocateSpec in project cloudstack by apache.

the class VirtualMachineMO method createLinkedClone.

public boolean createLinkedClone(String cloneName, ManagedObjectReference morBaseSnapshot, ManagedObjectReference morFolder, ManagedObjectReference morResourcePool, ManagedObjectReference morDs) throws Exception {
    assert (morBaseSnapshot != null);
    assert (morFolder != null);
    assert (morResourcePool != null);
    assert (morDs != null);
    VirtualDisk[] independentDisks = getAllIndependentDiskDevice();
    VirtualMachineRelocateSpec rSpec = new VirtualMachineRelocateSpec();
    if (independentDisks.length > 0) {
        List<VirtualMachineRelocateSpecDiskLocator> diskLocator = new ArrayList<VirtualMachineRelocateSpecDiskLocator>(independentDisks.length);
        for (int i = 0; i < independentDisks.length; i++) {
            VirtualMachineRelocateSpecDiskLocator loc = new VirtualMachineRelocateSpecDiskLocator();
            loc.setDatastore(morDs);
            loc.setDiskId(independentDisks[i].getKey());
            loc.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.MOVE_ALL_DISK_BACKINGS_AND_DISALLOW_SHARING.value());
            diskLocator.add(loc);
        }
        rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.CREATE_NEW_CHILD_DISK_BACKING.value());
        rSpec.getDisk().addAll(diskLocator);
    } else {
        rSpec.setDiskMoveType(VirtualMachineRelocateDiskMoveOptions.CREATE_NEW_CHILD_DISK_BACKING.value());
    }
    rSpec.setPool(morResourcePool);
    VirtualMachineCloneSpec cloneSpec = new VirtualMachineCloneSpec();
    cloneSpec.setPowerOn(false);
    cloneSpec.setTemplate(false);
    cloneSpec.setLocation(rSpec);
    cloneSpec.setSnapshot(morBaseSnapshot);
    ManagedObjectReference morTask = _context.getService().cloneVMTask(_mor, morFolder, cloneName, cloneSpec);
    boolean result = _context.getVimClient().waitForTask(morTask);
    if (result) {
        _context.waitForTaskProgressDone(morTask);
        return true;
    } else {
        s_logger.error("VMware cloneVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
    }
    return false;
}
Also used : VirtualMachineRelocateSpec(com.vmware.vim25.VirtualMachineRelocateSpec) VirtualMachineCloneSpec(com.vmware.vim25.VirtualMachineCloneSpec) ArrayList(java.util.ArrayList) VirtualDisk(com.vmware.vim25.VirtualDisk) VirtualMachineRelocateSpecDiskLocator(com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator) ArrayOfManagedObjectReference(com.vmware.vim25.ArrayOfManagedObjectReference) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 4 with VirtualMachineRelocateSpec

use of com.vmware.vim25.VirtualMachineRelocateSpec in project cloudstack by apache.

the class VirtualMachineMO method relocate.

public boolean relocate(ManagedObjectReference morTargetHost) throws Exception {
    VirtualMachineRelocateSpec relocateSpec = new VirtualMachineRelocateSpec();
    relocateSpec.setHost(morTargetHost);
    ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, null);
    boolean result = _context.getVimClient().waitForTask(morTask);
    if (result) {
        _context.waitForTaskProgressDone(morTask);
        return true;
    } else {
        s_logger.error("VMware relocateVM_Task failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
    }
    return false;
}
Also used : VirtualMachineRelocateSpec(com.vmware.vim25.VirtualMachineRelocateSpec) ArrayOfManagedObjectReference(com.vmware.vim25.ArrayOfManagedObjectReference) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Example 5 with VirtualMachineRelocateSpec

use of com.vmware.vim25.VirtualMachineRelocateSpec in project cloudstack by apache.

the class VirtualMachineMO method changeHost.

public boolean changeHost(VirtualMachineRelocateSpec relocateSpec) throws Exception {
    ManagedObjectReference morTask = _context.getService().relocateVMTask(_mor, relocateSpec, VirtualMachineMovePriority.DEFAULT_PRIORITY);
    boolean result = _context.getVimClient().waitForTask(morTask);
    if (result) {
        _context.waitForTaskProgressDone(morTask);
        return true;
    } else {
        s_logger.error("VMware RelocateVM_Task to change host failed due to " + TaskMO.getTaskFailureInfo(_context, morTask));
    }
    return false;
}
Also used : ArrayOfManagedObjectReference(com.vmware.vim25.ArrayOfManagedObjectReference) ManagedObjectReference(com.vmware.vim25.ManagedObjectReference)

Aggregations

ManagedObjectReference (com.vmware.vim25.ManagedObjectReference)10 ArrayOfManagedObjectReference (com.vmware.vim25.ArrayOfManagedObjectReference)8 VirtualMachineRelocateSpec (com.vmware.vim25.VirtualMachineRelocateSpec)8 VirtualDisk (com.vmware.vim25.VirtualDisk)4 VirtualMachineCloneSpec (com.vmware.vim25.VirtualMachineCloneSpec)4 VirtualMachineRelocateSpecDiskLocator (com.vmware.vim25.VirtualMachineRelocateSpecDiskLocator)4 ArrayList (java.util.ArrayList)3 StorageFilerTO (com.cloud.agent.api.to.StorageFilerTO)2 CloudException (com.cloud.exception.CloudException)2 InternalErrorException (com.cloud.exception.InternalErrorException)2 DatastoreMO (com.cloud.hypervisor.vmware.mo.DatastoreMO)2 VirtualMachineDiskInfoBuilder (com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder)2 VirtualMachineMO (com.cloud.hypervisor.vmware.mo.VirtualMachineMO)2 VmwareHypervisorHost (com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost)2 Pair (com.cloud.utils.Pair)2 CloudRuntimeException (com.cloud.utils.exception.CloudRuntimeException)2 IOException (java.io.IOException)2 UnsupportedEncodingException (java.io.UnsupportedEncodingException)2 ConnectException (java.net.ConnectException)2 RemoteException (java.rmi.RemoteException)2