package org.ovirt.engine.ui.uicommonweb.models.vms; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.ovirt.engine.core.common.action.MoveDiskParameters; import org.ovirt.engine.core.common.action.MoveDisksParameters; import org.ovirt.engine.core.common.action.MoveOrCopyImageGroupParameters; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.storage.Disk; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.common.businessentities.storage.DiskStorageType; import org.ovirt.engine.core.common.businessentities.storage.VolumeFormat; import org.ovirt.engine.core.common.businessentities.storage.VolumeType; import org.ovirt.engine.core.common.queries.IdQueryParameters; import org.ovirt.engine.core.common.queries.VdcQueryParametersBase; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.models.ListModel; import org.ovirt.engine.ui.uicommonweb.models.storage.MoveOrCopyDiskModel; import org.ovirt.engine.ui.uicompat.external.StringUtils; public class MoveDiskModel extends MoveOrCopyDiskModel { protected List<String> problematicDisksForWarning = new ArrayList<>(); public MoveDiskModel() { super(); setIsSourceStorageDomainNameAvailable(true); } @Override public void init(ArrayList<DiskImage> diskImages) { setDiskImages(diskImages); AsyncDataProvider.getInstance().getDiskList(new AsyncQuery<>(list -> { onInitAllDisks(list); onInitDisks(); })); } @Override protected void onInitDisks() { final ArrayList<DiskModel> disks = new ArrayList<>(); List<VdcQueryType> queries = new ArrayList<>(); List<VdcQueryParametersBase> params = new ArrayList<>(); for (DiskImage disk : getDiskImages()) { disks.add(DiskModel.diskToModel(disk)); queries.add(VdcQueryType.GetVmsByDiskGuid); params.add(new IdQueryParameters(disk.getId())); } Frontend.getInstance().runMultipleQueries(queries, params, result -> { for (int i = 0; i < result.getReturnValues().size(); i++) { Map<Boolean, List<VM>> resultValue = result.getReturnValues().get(i).getReturnValue(); disks.get(i).setPluggedToRunningVm(!isAllVmsDown(resultValue)); } setDisks(disks); updateMoveWarning(disks); initStorageDomains(); }); } private void updateMoveWarning(ArrayList<DiskModel> disks) { List<String> liveMigrateDisks = new ArrayList<>(); for (DiskModel diskModel : disks) { if (diskModel.isPluggedToRunningVm()) { liveMigrateDisks.add(diskModel.getAlias().getEntity()); } } if (!liveMigrateDisks.isEmpty()) { setMessage(messages.moveDisksWhileVmRunning(StringUtils.join(liveMigrateDisks, ", "))); //$NON-NLS-1$ } } @Override protected void initStorageDomains() { Disk disk = getDisks().get(0).getDisk(); if (disk.getDiskStorageType() != DiskStorageType.IMAGE) { return; } AsyncDataProvider.getInstance().getStorageDomainList(new AsyncQuery<>(storageDomains -> onInitStorageDomains(storageDomains)), ((DiskImage) disk).getStoragePoolId()); } @Override protected void postInitStorageDomains() { super.postInitStorageDomains(); // Add warning for raw/thin disks that reside on a file domain // and selected to be cold moved to a block domain (as it will cause // the disks to become preallocated, and it may consume considerably // more space on the target domain). for (final DiskModel diskModel : getDisks()) { ListModel<StorageDomain> sourceStorageDomains = diskModel.getSourceStorageDomain(); if (sourceStorageDomains.getItems().iterator().hasNext() && !sourceStorageDomains.getItems().iterator().next().getStorageType().isFileDomain()) { continue; } DiskImage diskImage = (DiskImage) diskModel.getDisk(); if (diskImage.getVolumeType() != VolumeType.Sparse || diskImage.getVolumeFormat() != VolumeFormat.RAW) { continue; } diskModel.getStorageDomain().getSelectedItemChangedEvent().addListener((ev, sender, args) -> updateProblematicDisk(diskModel)); updateProblematicDisk(diskModel); } } private void updateProblematicDisk(DiskModel diskModel) { StorageDomain storageDomain = diskModel.getStorageDomain().getSelectedItem(); if (storageDomain == null) { return; } String diskAlias = diskModel.getDisk().getDiskAlias(); if (storageDomain.getStorageType().isBlockDomain()) { if (!problematicDisksForWarning.contains(diskAlias)) { problematicDisksForWarning.add(diskAlias); } } else { problematicDisksForWarning.remove(diskAlias); } if (!problematicDisksForWarning.isEmpty()) { getDynamicWarning().setEntity(messages.moveDisksPreallocatedWarning( StringHelper.join(", ", problematicDisksForWarning.toArray()))); //$NON-NLS-1$ getDynamicWarning().setIsAvailable(true); } else { getDynamicWarning().setIsAvailable(false); } } @Override protected VdcActionType getActionType() { return VdcActionType.MoveDisks; } @Override protected String getWarning(List<String> disks) { return messages.cannotMoveDisks(StringHelper.join(", ", disks.toArray())); //$NON-NLS-1$ } @Override protected String getNoActiveSourceDomainMessage() { return constants.sourceStorageDomainIsNotActiveMsg(); } @Override protected String getNoActiveTargetDomainMessage() { return constants.noActiveTargetStorageDomainAvailableMsg(); } @Override protected MoveOrCopyImageGroupParameters createParameters(Guid sourceStorageDomainGuid, Guid destStorageDomainGuid, DiskImage disk) { MoveDiskParameters moveDiskParameters = new MoveDiskParameters(disk.getImageId(), sourceStorageDomainGuid, destStorageDomainGuid); moveDiskParameters.setImageGroupID(disk.getId()); return moveDiskParameters; } @Override protected void doExecute() { super.doExecute(); ArrayList<VdcActionParametersBase> parameters = getParameters(); if (parameters.isEmpty()) { cancel(); return; } MoveDisksParameters moveDisksParameters = new MoveDisksParameters((List) parameters); Frontend.getInstance().runAction(getActionType(), moveDisksParameters, result -> { MoveDiskModel localModel = (MoveDiskModel) result.getState(); localModel.cancel(); }, this); } @Override protected boolean allowedStorageDomain(List<StorageDomain> sourceActiveStorageDomains, DiskImage diskImage, DiskModel templateDisk, StorageDomain sd) { // can not move to the same storage domain if (sourceActiveStorageDomains.contains(sd)) { return false; } return super.allowedStorageDomain(sourceActiveStorageDomains, diskImage, templateDisk, sd); } }