package org.ovirt.engine.ui.uicommonweb.models.vms; import java.util.ArrayList; 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.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.compat.Guid; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.ui.frontend.AsyncCallback; import org.ovirt.engine.ui.frontend.AsyncQuery; 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.TabName; import org.ovirt.engine.ui.uicommonweb.models.pools.PoolModel; import org.ovirt.engine.ui.uicommonweb.validation.HostWithProtocolAndPortAddressValidation; import org.ovirt.engine.ui.uicommonweb.validation.IValidation; import org.ovirt.engine.ui.uicommonweb.validation.IntegerValidation; import org.ovirt.engine.ui.uicommonweb.validation.LengthValidation; import org.ovirt.engine.ui.uicommonweb.validation.NotEmptyValidation; import org.ovirt.engine.ui.uicommonweb.validation.PoolNameValidation; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.Event; import org.ovirt.engine.ui.uicompat.EventArgs; public abstract class PoolModelBehaviorBase extends VmModelBehaviorBase<PoolModel> { private final Event<EventArgs> poolModelBehaviorInitializedEvent = new Event<>("PoolModelBehaviorInitializedEvent", //$NON-NLS-1$ NewPoolModelBehavior.class); public Event<EventArgs> getPoolModelBehaviorInitializedEvent() { return poolModelBehaviorInitializedEvent; } @Override public void initialize(SystemTreeItemModel systemTreeSelectedItem) { super.initialize(systemTreeSelectedItem); getModel().getIsSoundcardEnabled().setIsChangeable(true); getModel().getDisksAllocationModel().setIsVolumeFormatAvailable(true); getModel().getDisksAllocationModel().setIsThinProvisioning(true); getModel().getDisksAllocationModel().setIsAliasChangable(true); getModel().getProvisioning().setIsAvailable(false); getModel().getProvisioning().setEntity(false); AsyncDataProvider.getInstance().getDataCenterByClusterServiceList(asyncQuery(returnValue -> { final List<StoragePool> dataCenters = new ArrayList<>(); for (StoragePool a : returnValue) { if (a.getStatus() == StoragePoolStatus.Up) { dataCenters.add(a); } } if (!dataCenters.isEmpty()) { postDataCentersLoaded(dataCenters); } else { getModel().disableEditing(ConstantsManager.getInstance().getConstants().notAvailableWithNoUpDC()); } }), true, false); getModel().getSpiceProxyEnabled().setEntity(false); getModel().getSpiceProxy().setIsChangeable(false); getModel().getSpiceProxyEnabled().getEntityChangedEvent().addListener((ev, sender, args) -> getModel().getSpiceProxy().setIsChangeable(getModel().getSpiceProxyEnabled().getEntity())); } protected void postDataCentersLoaded(final List<StoragePool> dataCenters) { AsyncDataProvider.getInstance().getClusterListByService( new AsyncQuery<>(new AsyncCallback<List<Cluster>>() { @Override public void onSuccess(List<Cluster> clusters) { List<Cluster> filteredClusters = filterClusters(clusters); getModel().setDataCentersAndClusters(getModel(), dataCenters, filteredClusters, null); initCdImage(); getPoolModelBehaviorInitializedEvent().raise(this, EventArgs.EMPTY); } }), true, false); } protected abstract List<Cluster> filterClusters(List<Cluster> clusters); protected void setupWindowModelFrom(final VmBase vmBase) { if (vmBase != null) { updateQuotaByCluster(vmBase.getQuotaId(), vmBase.getQuotaName()); // Copy VM parameters from template. buildModel(vmBase, (source, destination) -> { setSelectedOSType(vmBase, getModel().getSelectedCluster().getArchitecture()); getModel().getVmType().setSelectedItem(vmBase.getVmType()); getModel().getIsRunAndPause().setEntity(false); boolean hasCd = !StringHelper.isNullOrEmpty(vmBase.getIsoPath()); getModel().getCdImage().setIsChangeable(hasCd); getModel().getCdAttached().setEntity(hasCd); if (hasCd) { getModel().getCdImage().setSelectedItem(vmBase.getIsoPath()); } updateTimeZone(vmBase.getTimeZone()); if (!vmBase.getId().equals(Guid.Empty)) { getModel().getStorageDomain().setIsChangeable(true); initDisks(); } else { getModel().getStorageDomain().setIsChangeable(false); getModel().setIsDisksAvailable(false); getModel().setDisks(null); } getModel().getProvisioning().setEntity(false); initStorageDomains(); InstanceType selectedInstanceType = getModel().getInstanceTypes().getSelectedItem(); int instanceTypeMinAllocatedMemory = selectedInstanceType != null ? selectedInstanceType.getMinAllocatedMem() : 0; // do not update if specified on template or instance type if (vmBase.getMinAllocatedMem() == 0 && instanceTypeMinAllocatedMemory == 0) { updateMinAllocatedMemory(); } getModel().getAllowConsoleReconnect().setEntity(vmBase.isAllowConsoleReconnect()); toggleAutoSetVmHostname(); getModel().getVmInitModel().init(vmBase); getModel().getVmInitEnabled().setEntity(vmBase.getVmInit() != null); if (getModel().getSelectedCluster() != null) { updateCpuProfile(getModel().getSelectedCluster().getId(), vmBase.getCpuProfileId()); } getModel().getCpuSharesAmount().setEntity(vmBase.getCpuShares()); updateCpuSharesSelection(); // A workaround for setting the current saved CustomCompatibilityVersion value after // it was reset by getTemplateWithVersion event getModel().getCustomCompatibilityVersion().setSelectedItem(getSavedCurrentCustomCompatibilityVersion()); setCustomCompatibilityVersionChangeInProgress(false); }); } } @Override protected void buildModel(VmBase vmBase, BuilderExecutor.BuilderExecutionFinished<VmBase, UnitVmModel> callback) { new BuilderExecutor<>(callback, new CoreVmBaseToUnitBuilder()) .build(vmBase, getModel()); } @Override public void postDataCenterWithClusterSelectedItemChanged() { updateDefaultHost(); updateCustomPropertySheet(); updateMinAllocatedMemory(); updateNumOfSockets(); updateOSValues(); if (getModel().getTemplateWithVersion().getSelectedItem() != null) { VmTemplate template = getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion(); updateQuotaByCluster(template.getQuotaId(), template.getQuotaName()); } updateMemoryBalloon(); updateCpuSharesAvailability(); updateVirtioScsiAvailability(); } @Override public void defaultHost_SelectedItemChanged() { updateCdImage(); } @Override public void provisioning_SelectedItemChanged() { } @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; } Cluster cluster = getModel().getSelectedCluster(); if (cluster == null) { return; } double overCommitFactor = 100.0 / cluster.getMaxVdsMemoryOverCommit(); getModel().getMinAllocatedMemory() .setEntity((int) (getModel().getMemSize().getEntity() * overCommitFactor)); } public void initCdImage() { updateCdImage(); } @Override public void updateIsDisksAvailable() { getModel().setIsDisksAvailable(getModel().getDisks() != null && getModel().getProvisioning().getIsChangable()); } @Override public boolean validate() { boolean isNew = getModel().getIsNew(); int maxAllowedVms = getMaxVmsInPool(); int assignedVms = getModel().getAssignedVms().asConvertible().integer(); int futureNumOfDesktops = (isNew ? 0 : assignedVms) + getModel().getNumOfDesktops().getEntity(); getModel().getNumOfDesktops().validateEntity( new IValidation[] { new NotEmptyValidation(), new LengthValidation(4), new IntegerValidation(isNew ? 1 : 0, isNew ? maxAllowedVms : maxAllowedVms - assignedVms) }); getModel().getPrestartedVms().validateEntity( new IValidation[] { new NotEmptyValidation(), new IntegerValidation(0, futureNumOfDesktops) }); getModel().getMaxAssignedVmsPerUser().validateEntity( new IValidation[] { new NotEmptyValidation(), new IntegerValidation(1, futureNumOfDesktops) }); getModel().setValidTab(TabName.GENERAL_TAB, getModel().isValidTab(TabName.GENERAL_TAB) && getModel().getName().getIsValid() && getModel().getNumOfDesktops().getIsValid() && getModel().getPrestartedVms().getIsValid() && getModel().getMaxAssignedVmsPerUser().getIsValid()); getModel().setValidTab(TabName.POOL_TAB, true); if (getModel().getSpiceProxyEnabled().getEntity()) { getModel().getSpiceProxy().validateEntity(new IValidation[]{ new HostWithProtocolAndPortAddressValidation()}); } else { getModel().getSpiceProxy().setIsValid(true); } return super.validate() && getModel().getName().getIsValid() && getModel().getNumOfDesktops().getIsValid() && getModel().getPrestartedVms().getIsValid() && getModel().getMaxAssignedVmsPerUser().getIsValid() && getModel().getSpiceProxy().getIsValid(); } @Override public IValidation getNameAllowedCharactersIValidation() { return new PoolNameValidation(); } private void toggleAutoSetVmHostname() { // always switch off auto setting of hostname for pool VMs getModel().getVmInitModel().disableAutoSetHostname(); } @Override public void setCustomCompatibilityVersionChangeInProgress(boolean isCustomCompatibilityVersionChangeInProgress) { this.isCustomCompatibilityVersionChangeInProgress = isCustomCompatibilityVersionChangeInProgress; } }