package org.ovirt.engine.ui.uicommonweb.models.vms; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.List; import org.ovirt.engine.core.common.businessentities.ActionGroup; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.DisplayType; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StorageDomainStatus; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmBase; import org.ovirt.engine.core.common.businessentities.VmTemplate; import org.ovirt.engine.core.common.businessentities.comparators.DiskByDiskAliasComparator; import org.ovirt.engine.core.common.businessentities.comparators.NameableComparator; import org.ovirt.engine.core.common.businessentities.storage.CinderDisk; 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.StorageType; import org.ovirt.engine.core.common.businessentities.storage.VolumeType; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.ui.frontend.AsyncQuery; import org.ovirt.engine.ui.uicommonweb.Linq; import org.ovirt.engine.ui.uicommonweb.builders.BuilderExecutor; import org.ovirt.engine.ui.uicommonweb.builders.vm.CommonVmBaseToUnitBuilder; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; import org.ovirt.engine.ui.uicommonweb.models.ListModel; import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemModel; import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemType; import org.ovirt.engine.ui.uicommonweb.models.storage.DisksAllocationModel; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.UIConstants; public class NewTemplateVmModelBehavior extends VmModelBehaviorBase<UnitVmModel> { private final UIConstants constants = ConstantsManager.getInstance().getConstants(); private VM vm; public NewTemplateVmModelBehavior() { } public NewTemplateVmModelBehavior(VM vm) { this.vm = vm; } public void setVm(VM vm) { this.vm = vm; getModel().getIsSingleQxlEnabled().setEntity(vm.getSingleQxlPci()); } protected VM getVm() { return vm; } @Override public void initialize(SystemTreeItemModel systemTreeSelectedItem) { super.initialize(systemTreeSelectedItem); getModel().getVmInitEnabled().setEntity(vm.getVmInit() != null); getModel().getVmInitModel().init(vm.getStaticData()); getModel().getVmType().setIsChangeable(true); getModel().getCopyPermissions().setIsAvailable(true); DisksAllocationModel disksAllocationModel = getModel().getDisksAllocationModel(); disksAllocationModel.setIsVolumeFormatAvailable(true); disksAllocationModel.setIsVolumeFormatChangeable(true); disksAllocationModel.setIsAliasChangable(true); disksAllocationModel.setContainer(getModel()); disksAllocationModel.setIsThinProvisioning(false); AsyncDataProvider.getInstance().getDataCenterById(new AsyncQuery<>( dataCenter -> { if (dataCenter == null) { disableNewTemplateModel(ConstantsManager.getInstance() .getConstants() .dataCenterIsNotAccessibleMsg()); } else { AsyncDataProvider.getInstance().getClusterListByService( new AsyncQuery<>(clusters -> { List<Cluster> filteredClusters = AsyncDataProvider.getInstance().filterByArchitecture(clusters, vm.getClusterArch()); getModel().setDataCentersAndClusters(getModel(), Arrays.asList(dataCenter), filteredClusters, vm.getClusterId()); initTemplate(); }), true, false); AsyncDataProvider.getInstance().isSoundcardEnabled(new AsyncQuery<>( returnValue -> getModel().getIsSoundcardEnabled().setEntity(returnValue)), vm.getId()); } }), vm.getStoragePoolId()); } protected void updateTemplate() { final DataCenterWithCluster dataCenterWithCluster = getModel().getDataCenterWithClustersList().getSelectedItem(); StoragePool dataCenter = dataCenterWithCluster == null ? null : dataCenterWithCluster.getDataCenter(); if (dataCenter == null) { return; } // Filter according to system tree selection. if (getSystemTreeSelectedItem() != null && getSystemTreeSelectedItem().getType() == SystemTreeItemType.Storage) { final StorageDomain storage = (StorageDomain) getSystemTreeSelectedItem().getEntity(); AsyncDataProvider.getInstance().getTemplateListByDataCenter(new AsyncQuery<>( templatesByDataCenter -> AsyncDataProvider.getInstance().getTemplateListByStorage(new AsyncQuery<>( templatesByStorage -> { VmTemplate blankTemplate = Linq.firstOrNull(templatesByDataCenter, new Linq.IdPredicate<>(Guid.Empty)); if (blankTemplate != null) { templatesByStorage.add(0, blankTemplate); } ArrayList<VmTemplate> templateList = AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templatesByStorage, dataCenterWithCluster.getCluster().getArchitecture()); postInitTemplate(templateList); }), storage.getId())), dataCenter.getId()); } else { AsyncDataProvider.getInstance().getTemplateListByDataCenter(new AsyncQuery<>( templates -> postInitTemplate(AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templates, dataCenterWithCluster.getCluster().getArchitecture()))), dataCenter.getId()); } } private void postInitTemplate(List<VmTemplate> templates) { List<VmTemplate> baseWithoutBlank = filterOutBlank(keepBaseTemplates(templates)); getModel().getIsSubTemplate().setEntity(false); if (baseWithoutBlank.isEmpty()) { // it is not allowed to create sub-templates of Blank template getModel().getIsSubTemplate().setIsChangeable(false, constants.someNonDefaultTemplateHasToExistFirst()); return; } getModel().getIsSubTemplate().setIsChangeable(true); VmTemplate currentTemplate = Linq.firstOrNull(templates, new Linq.IdPredicate<>(vm.getVmtGuid())); getModel().getBaseTemplate().setItems(baseWithoutBlank); getModel().getBaseTemplate().setSelectedItem(Linq.firstOrNull(baseWithoutBlank, new Linq.IdPredicate<>(currentTemplate.getBaseTemplateId()))); } private List<VmTemplate> filterOutBlank(List<VmTemplate> templates) { final List<VmTemplate> result = new ArrayList<>(); for (VmTemplate template : templates) { if (!template.isBlank()) { result.add(template); } } return result; } @Override public void dataCenterWithClusterSelectedItemChanged() { super.dataCenterWithClusterSelectedItemChanged(); // If a VM has at least one disk, present its storage domain. AsyncDataProvider.getInstance().getVmDiskList(asyncQuery( vmDisks -> { ArrayList<Disk> imageDisks = new ArrayList<>(); for (Disk disk : vmDisks) { if (disk.isShareable() || disk.isDiskSnapshot()) { continue; } if (disk.getDiskStorageType() == DiskStorageType.IMAGE || disk.getDiskStorageType() == DiskStorageType.CINDER) { imageDisks.add(disk); } } initStorageDomains(); initDisks(imageDisks); VmModelHelper.sendWarningForNonExportableDisks(getModel(), vmDisks, VmModelHelper.WarningType.VM_TEMPLATE); }), vm.getId(), true); } private void initDisks(ArrayList<Disk> disks) { Collections.sort(disks, new DiskByDiskAliasComparator()); ArrayList<DiskModel> list = new ArrayList<>(); for (Disk disk : disks) { DiskModel diskModel = new DiskModel(); switch (disk.getDiskStorageType()) { case IMAGE: DiskImage diskImage = (DiskImage) disk; diskModel.setSize(new EntityModel<>((int) diskImage.getSizeInGigabytes())); ListModel volumes = new ListModel(); volumes.setItems(diskImage.getVolumeType() == VolumeType.Preallocated ? new ArrayList<>(Arrays.asList(new VolumeType[]{VolumeType.Preallocated})) : AsyncDataProvider.getInstance().getVolumeTypeList(), diskImage.getVolumeType()); diskModel.setVolumeType(volumes); diskModel.getAlias().setEntity(diskImage.getDiskAlias()); break; case CINDER: CinderDisk cinderDisk = (CinderDisk) disk; diskModel.setSize(new EntityModel<>((int) cinderDisk.getSizeInGigabytes())); ListModel volumeTypes = new ListModel(); volumeTypes.setItems(new ArrayList<>(Arrays.asList(cinderDisk.getVolumeType())), cinderDisk.getVolumeType()); diskModel.setVolumeType(volumeTypes); diskModel.getAlias().setEntity(cinderDisk.getDiskAlias()); diskModel.getVolumeFormat().setIsChangeable(false); break; } diskModel.setDisk(disk); list.add(diskModel); diskModel.getVolumeFormat().setIsAvailable(true); } getModel().setDisks(list); } @Override public void postDataCenterWithClusterSelectedItemChanged() { updateQuotaByCluster(vm.getQuotaId(), vm.getQuotaName()); updateMemoryBalloon(); updateCpuSharesAvailability(); updateVirtioScsiAvailability(); updateOSValues(); updateTemplate(); updateNumOfSockets(); if(getModel().getSelectedCluster() != null) { updateCpuProfile(getModel().getSelectedCluster().getId(), vm.getCpuProfileId()); } updateCustomPropertySheet(); getModel().getCustomPropertySheet().deserialize(vm.getCustomProperties()); updateLeaseStorageDomains(vm.getLeaseStorageDomainId()); } @Override public void oSType_SelectedItemChanged() { super.oSType_SelectedItemChanged(); Integer osType = getModel().getOSType().getSelectedItem(); if (osType != null) { getVirtioScsiUtil().updateVirtioScsiEnabled(vm.getId(), osType); } } @Override public void defaultHost_SelectedItemChanged() { } @Override public void provisioning_SelectedItemChanged() { } private void initTemplate() { // Update model state according to VM properties. buildModel(this.vm.getStaticData(), (source, destination) -> { updateSelectedCdImage(vm.getStaticData()); updateTimeZone(vm.getTimeZone()); updateConsoleDevice(vm.getId()); getModel().getStorageDomain().setIsChangeable(true); getModel().getProvisioning().setIsAvailable(false); // Select display protocol. DisplayType displayType = vm.getDefaultDisplayType(); if (getModel().getDisplayType().getItems().contains(displayType)) { getModel().getDisplayType().setSelectedItem(displayType); } initPriority(vm.getPriority()); }); } @Override protected void buildModel(VmBase vmBase, BuilderExecutor.BuilderExecutionFinished<VmBase, UnitVmModel> callback) { new BuilderExecutor<>(callback, new CommonVmBaseToUnitBuilder()) .build(vmBase, getModel()); } @Override public void initStorageDomains() { AsyncDataProvider.getInstance().getPermittedStorageDomainsByStoragePoolId(asyncQuery( storageDomains -> { ArrayList<StorageDomain> activeStorageDomainList = new ArrayList<>(); for (StorageDomain storageDomain : storageDomains) { if (storageDomain.getStatus() == StorageDomainStatus.Active && storageDomain.getStorageDomainType().isDataDomain()) { activeStorageDomainList.add(storageDomain); } } for (DiskModel diskModel : getModel().getDisks()) { if (diskModel.getDisk().getDiskStorageType() == DiskStorageType.IMAGE) { DiskImage diskImage = (DiskImage) diskModel.getDisk(); List<StorageDomain> activeDiskStorages = Linq.getStorageDomainsByIds(diskImage.getStorageIds(), activeStorageDomainList); if (activeDiskStorages.isEmpty()) { disableNewTemplateModel( ConstantsManager.getInstance() .getMessages() .vmStorageDomainIsNotAccessible()); return; } } } if (activeStorageDomainList.size() > 0) { if (getSystemTreeSelectedItem() != null && getSystemTreeSelectedItem().getType() == SystemTreeItemType.Storage) { StorageDomain selectStorage = (StorageDomain) getSystemTreeSelectedItem().getEntity(); StorageDomain s = Linq.firstOrNull(activeStorageDomainList, new Linq.IdPredicate<>(selectStorage.getId())); activeStorageDomainList = new ArrayList<>(Arrays.asList(new StorageDomain[]{s})); getModel().getStorageDomain().setItems(activeStorageDomainList); getModel().getStorageDomain().setIsChangeable(false); getModel().getStorageDomain().setSelectedItem(s); } else { getModel().getStorageDomain().setItems(activeStorageDomainList); getModel().getStorageDomain().setIsChangeable(true); } } else { disableNewTemplateModel(ConstantsManager.getInstance() .getMessages() .noActiveStorageDomain()); } ArrayList<DiskModel> disks = (ArrayList<DiskModel>) getModel().getDisksAllocationModel().getDisks(); Collections.sort(activeStorageDomainList, new NameableComparator()); if (disks != null) { List<DiskModel> diskImages = Linq.filterDisksByType(disks, DiskStorageType.IMAGE); for (DiskModel diskModel : diskImages) { diskModel.getStorageDomain().setItems(activeStorageDomainList); } List<DiskModel> cinderDisks = Linq.filterDisksByType(disks, DiskStorageType.CINDER); if (!cinderDisks.isEmpty()) { Collection<StorageDomain> cinderStorageDomains = Linq.filterStorageDomainsByStorageType(storageDomains, StorageType.CINDER); initStorageDomainsForCinderDisks(cinderDisks, cinderStorageDomains); } } }), vm.getStoragePoolId(), ActionGroup.CREATE_TEMPLATE); } private void initStorageDomainsForCinderDisks(List<DiskModel> cinderDisks, Collection<StorageDomain> cinderStorageDomains) { for (DiskModel diskModel : cinderDisks) { CinderDisk cinderDisk = (CinderDisk) diskModel.getDisk(); diskModel.getStorageDomain().setItems(Linq.filterStorageDomainById( cinderStorageDomains, cinderDisk.getStorageIds().get(0))); diskModel.getDiskProfile().setIsChangeable(false); diskModel.getDiskProfile().setChangeProhibitionReason( ConstantsManager.getInstance().getConstants().notSupportedForCinderDisks()); } } private void disableNewTemplateModel(String errMessage) { getModel().setIsValid(false); getModel().setMessage(errMessage); getModel().getName().setIsChangeable(false); getModel().getDescription().setIsChangeable(false); getModel().getDataCenterWithClustersList().setIsChangeable(false); getModel().getComment().setIsChangeable(false); getModel().getStorageDomain().setIsChangeable(false); getModel().getIsTemplatePublic().setIsChangeable(false); getModel().getDefaultCommand().setIsAvailable(false); } @Override public void postOsItemChanged() { if (vm != null) { getModel().getOSType().setSelectedItem(vm.getOs()); } } @Override protected void baseTemplateSelectedItemChanged() { if (getModel().getBaseTemplate().getSelectedItem() != null && getModel().getIsSubTemplate().getEntity()) { // template.name for version should be the same as the base template name getModel().getName().setEntity(getModel().getBaseTemplate().getSelectedItem().getName()); } } @Override protected void isSubTemplateEntityChanged() { getModel().getName().setIsChangeable(!getModel().getIsSubTemplate().getEntity()); if (!getModel().getIsSubTemplate().getEntity()) { getModel().getName().setEntity(""); //$NON-NLS-1$ } else { // there will always be at least 'Blank' base template getModel().getBaseTemplate().setSelectedItem(getModel().getBaseTemplate().getItems().iterator().next()); // copy any entered name to be the template-version name getModel().getTemplateVersionName().setEntity(getModel().getName().getEntity()); getModel().getName().setEntity(getModel().getBaseTemplate().getSelectedItem().getName()); } } @Override public void enableSinglePCI(boolean enabled) { super.enableSinglePCI(enabled); getModel().getIsSingleQxlEnabled().setEntity(vm != null ? vm.getSingleQxlPci() : false); } }