package org.ovirt.engine.ui.uicommonweb.models.vms; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.ovirt.engine.core.common.businessentities.Cluster; import org.ovirt.engine.core.common.businessentities.InstanceType; import org.ovirt.engine.core.common.businessentities.StorageDomain; import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.StoragePoolStatus; import org.ovirt.engine.core.common.businessentities.VmBase; import org.ovirt.engine.core.common.businessentities.VmTemplate; import org.ovirt.engine.core.common.businessentities.VmType; import org.ovirt.engine.core.common.businessentities.network.VnicProfileView; import org.ovirt.engine.core.common.businessentities.storage.DiskImage; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.StringHelper; 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.CoreVmBaseToUnitBuilder; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemModel; import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemType; import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion; import org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager; import org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.NewVmInstanceTypeManager; import org.ovirt.engine.ui.uicompat.ConstantsManager; public class NewVmModelBehavior extends VmModelBehaviorBase<UnitVmModel> { private InstanceTypeManager instanceTypeManager; private boolean updateStatelessFlag = true; @Override public void initialize(SystemTreeItemModel systemTreeSelectedItem) { super.initialize(systemTreeSelectedItem); getModel().getIsSoundcardEnabled().setIsChangeable(true); getModel().getVmType().setIsChangeable(true); getModel().getVmId().setIsAvailable(true); getModel().getLabelList().setIsAvailable(true); loadDataCenters(); initPriority(0); getModel().getVmInitModel().init(null); instanceTypeManager = new NewVmInstanceTypeManager(getModel()); } @Override protected void commonInitialize() { super.commonInitialize(); getModel().getIsStateless().getEntityChangedEvent().addListener(new UpdateTemplateWithVersionListener() { @Override protected void beforeUpdate() { // will be moved back in the callback which can be async updateStatelessFlag = false; } @Override protected boolean isAddLatestVersion() { return getModel().getIsStateless().getEntity(); } }); } protected void loadDataCenters() { AsyncDataProvider.getInstance().getDataCenterByClusterServiceList(new AsyncQuery<>( returnValue -> { final ArrayList<StoragePool> dataCenters = new ArrayList<>(); for (StoragePool a : returnValue) { if (a.getStatus() == StoragePoolStatus.Up) { dataCenters.add(a); } } if (!dataCenters.isEmpty()) { AsyncDataProvider.getInstance().getClusterListByService( new AsyncQuery<>(clusterList -> { List<Cluster> filteredClusterList = AsyncDataProvider.getInstance().filterClustersWithoutArchitecture(clusterList); getModel().setDataCentersAndClusters(getModel(), dataCenters, filteredClusterList, null); initCdImage(); }), true, false); } else { getModel().disableEditing(ConstantsManager.getInstance().getConstants().notAvailableWithNoUpDC()); } }), true, false); } @Override public void templateWithVersion_SelectedItemChanged() { TemplateWithVersion selectedTemplateWithVersion = getModel().getTemplateWithVersion().getSelectedItem(); if (selectedTemplateWithVersion != null) { VmTemplate selectedTemplate = selectedTemplateWithVersion.getTemplateVersion(); selectedTemplateChanged(selectedTemplate); } } private void selectedTemplateChanged(final VmTemplate template) { // Copy VM parameters from template. buildModel(template, (source, destination) -> { setSelectedOSType(template, getModel().getSelectedCluster().getArchitecture()); doChangeDefaultHost(template.getDedicatedVmForVdsList()); if (updateStatelessFlag) { getModel().getIsStateless().setEntity(template.isStateless()); } updateStatelessFlag = true; getModel().getIsRunAndPause().setEntity(template.isRunAndPause()); boolean hasCd = !StringHelper.isNullOrEmpty(template.getIsoPath()); getModel().getCdImage().setIsChangeable(hasCd); getModel().getCdAttached().setEntity(hasCd); if (hasCd) { getModel().getCdImage().setSelectedItem(template.getIsoPath()); } updateTimeZone(template.getTimeZone()); if (!template.getId().equals(Guid.Empty)) { getModel().getStorageDomain().setIsChangeable(true); getModel().getProvisioning().setIsChangeable(true); getModel().getCopyPermissions().setIsAvailable(true); initDisks(); } else { getModel().getStorageDomain().setIsChangeable(false); getModel().getProvisioning().setIsChangeable(false); getModel().getCopyPermissions().setIsAvailable(false); getModel().setDisks(null); getModel().setIsDisksAvailable(false); getModel().getInstanceImages().setIsChangeable(true); } getModel().getAllowConsoleReconnect().setEntity(template.isAllowConsoleReconnect()); getModel().getVmType().setSelectedItem(template.getVmType()); updateRngDevice(template.getId()); initStorageDomains(); InstanceType selectedInstanceType = getModel().getInstanceTypes().getSelectedItem(); int instanceTypeMinAllocatedMemory = selectedInstanceType != null ? selectedInstanceType.getMinAllocatedMem() : 0; // do not update if specified on template or instance type if (template.getMinAllocatedMem() == 0 && instanceTypeMinAllocatedMemory == 0) { updateMinAllocatedMemory(); } updateQuotaByCluster(template.getQuotaId(), template.getQuotaName()); getModel().getCustomPropertySheet().deserialize(template.getCustomProperties()); getModel().getVmInitModel().init(template); getModel().getVmInitEnabled().setEntity(template.getVmInit() != null); if (getModel().getSelectedCluster() != null) { updateCpuProfile(getModel().getSelectedCluster().getId(), template.getCpuProfileId()); } provisioning_SelectedItemChanged(); updateMigrationForLocalSD(); // A workaround for setting the current saved CustomCompatibilityVersion value after // it was reset by getTemplateWithVersion event getModel().getCustomCompatibilityVersion().setSelectedItem(getSavedCurrentCustomCompatibilityVersion()); setCustomCompatibilityVersionChangeInProgress(false); updateLeaseStorageDomains(template.getLeaseStorageDomainId()); }); } @Override protected void buildModel(VmBase template, BuilderExecutor.BuilderExecutionFinished callback) { new BuilderExecutor<>(callback, new CoreVmBaseToUnitBuilder()) .build(template, getModel()); } @Override public void postDataCenterWithClusterSelectedItemChanged() { deactivateInstanceTypeManager(() -> getInstanceTypeManager().updateAll()); updateDefaultHost(); updateCustomPropertySheet(); updateMinAllocatedMemory(); updateNumOfSockets(); if (getModel().getTemplateWithVersion().getSelectedItem() != null) { VmTemplate template = getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion(); updateQuotaByCluster(template.getQuotaId(), template.getQuotaName()); } updateCpuPinningVisibility(); updateTemplate(); updateOSValues(); updateMemoryBalloon(); updateCpuSharesAvailability(); updateVirtioScsiAvailability(); activateInstanceTypeManager(); } private boolean profilesExist(List<VnicProfileView> profiles) { return !profiles.isEmpty() && profiles.get(0) != null; } @Override public void defaultHost_SelectedItemChanged() { updateCdImage(); } @Override public void provisioning_SelectedItemChanged() { boolean provisioning = getModel().getProvisioning().getEntity(); getModel().getProvisioningThin_IsSelected().setEntity(!provisioning); getModel().getProvisioningClone_IsSelected().setEntity(provisioning); getModel().getDisksAllocationModel().setIsVolumeFormatAvailable(true); getModel().getDisksAllocationModel().setIsVolumeFormatChangeable(provisioning); getModel().getDisksAllocationModel().setIsThinProvisioning(!provisioning); getModel().getDisksAllocationModel().setIsAliasChangable(true); initStorageDomains(); } @Override public void oSType_SelectedItemChanged() { super.oSType_SelectedItemChanged(); VmTemplate template = getModel().getTemplateWithVersion().getSelectedItem() == null ? null : getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion(); Integer osType = getModel().getOSType().getSelectedItem(); if ((template != null || !basedOnCustomInstanceType()) && osType != null) { Guid id = basedOnCustomInstanceType() ? template.getId() : getModel().getInstanceTypes().getSelectedItem().getId(); updateVirtioScsiEnabledWithoutDetach(id, osType); } } @Override public void updateMinAllocatedMemory() { if (getModel().getMemSize().getEntity() == null) { return; } final Cluster cluster = getModel().getSelectedCluster(); if (cluster == null) { return; } double overCommitFactor = 100.0 / cluster.getMaxVdsMemoryOverCommit(); getModel().getMinAllocatedMemory() .setEntity((int) (getModel().getMemSize().getEntity() * overCommitFactor)); } private 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(asyncQuery( templatesByDataCenter -> AsyncDataProvider.getInstance().getTemplateListByStorage(asyncQuery( templatesByStorage -> { VmTemplate blankTemplate = Linq.firstOrNull(templatesByDataCenter, new Linq.IdPredicate<>(Guid.Empty)); if (blankTemplate != null) { templatesByStorage.add(0, blankTemplate); } List<VmTemplate> templateList = AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templatesByStorage, dataCenterWithCluster.getCluster().getArchitecture()); postInitTemplate(templateList); }), storage.getId())), dataCenter.getId()); } else { AsyncDataProvider.getInstance().getTemplateListByDataCenter(asyncQuery( templates -> postInitTemplate(AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templates, dataCenterWithCluster.getCluster().getArchitecture()))), dataCenter.getId()); } } protected void postInitTemplate(List<VmTemplate> templates) { initTemplateWithVersion(templates, null, false, getModel().getIsStateless().getEntity()); updateIsDisksAvailable(); } public void initCdImage() { DataCenterWithCluster dataCenterWithCluster = getModel().getDataCenterWithClustersList().getSelectedItem(); if (dataCenterWithCluster == null || dataCenterWithCluster.getDataCenter() == null) { return; } updateUserCdImage(dataCenterWithCluster.getDataCenter().getId()); } @Override public void updateIsDisksAvailable() { getModel().setIsDisksAvailable(getModel().getDisks() != null && !getModel().getDisks().isEmpty() && getModel().getProvisioning().getIsChangable()); } @Override public void vmTypeChanged(VmType vmType) { // provisioning thin -> false // provisioning clone -> true if (getModel().getProvisioning().getIsAvailable()) { getModel().getProvisioning().setEntity(vmType == VmType.Server); } super.vmTypeChanged(vmType); } @Override public InstanceTypeManager getInstanceTypeManager() { return instanceTypeManager; } @Override public void enableSinglePCI(boolean enabled) { super.enableSinglePCI(enabled); getModel().getIsSingleQxlEnabled().setEntity(enabled); } @Override protected void updateNumaEnabled() { super.updateNumaEnabled(); updateNumaEnabledHelper(); } @Override protected void initTemplateDisks(List<DiskImage> disks) { // can not mix template disks with instance images adjustInstanceImages(disks.isEmpty()); super.initTemplateDisks(disks); } private void adjustInstanceImages(boolean instanceImagesEnabled) { getModel().getInstanceImages().setIsChangeable(instanceImagesEnabled); // if disabling, remove all except the ghost if (!instanceImagesEnabled) { Collection<InstanceImageLineModel> keepImages = new ArrayList<>(); for (InstanceImageLineModel image : getModel().getInstanceImages().getItems()) { if (image.isGhost()) { keepImages.add(image); // only one ghost allowed break; } } getModel().getInstanceImages().setItems(keepImages); } } @Override public void setCustomCompatibilityVersionChangeInProgress(boolean isCustomCompatibilityVersionChangeInProgress) { this.isCustomCompatibilityVersionChangeInProgress = isCustomCompatibilityVersionChangeInProgress; } @Override protected TemplateWithVersion computeTemplateWithVersionToSelect( List<TemplateWithVersion> newItems, Guid previousTemplateId, boolean useLatest, boolean addLatest) { if (previousTemplateId == null) { return computeNewTemplateWithVersionToSelect(newItems, addLatest); } TemplateWithVersion oldTemplateToSelect = Linq.firstOrNull( newItems, new Linq.TemplateWithVersionPredicateForNewVm(previousTemplateId, useLatest)); return oldTemplateToSelect != null ? oldTemplateToSelect : computeNewTemplateWithVersionToSelect(newItems, addLatest); } }