Gilad Chaplik has uploaded a new change for review. Change subject: frontend: add numa support to VM dialog ......................................................................
frontend: add numa support to VM dialog Change-Id: I05b83028b722088e39ad7156c77ad4eb479dc241 Signed-off-by: Gilad Chaplik <gchap...@redhat.com> --- M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractVmPopupView.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/DraggableVirtualNumaPanel.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/popup/AbstractVmBasedPopupPresenterWidget.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonUnitToVmBaseBuilder.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonVmBaseToUnitBuilder.java A frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java A frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VmNumaSupportModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java M frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java M frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties M frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/vm/VmPopupPresenterWidget.java 18 files changed, 413 insertions(+), 11 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/13/32913/1 diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java index 38999a6..bee4e17 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java @@ -1939,4 +1939,10 @@ @DefaultStringValue("Un pin virtual node") String unPinNode(); + @DefaultStringValue("Tune Mode") + String numaTunaModeLabel(); + + @DefaultStringValue("vNuma Node Count") + String numaNodeCountLabel(); + } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractVmPopupView.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractVmPopupView.java index 7bdae86..4f0dd67 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractVmPopupView.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/AbstractVmPopupView.java @@ -6,6 +6,7 @@ import org.ovirt.engine.ui.common.CommonApplicationResources; import org.ovirt.engine.ui.common.widget.AbstractUiCommandButton; +import org.ovirt.engine.ui.common.widget.HasUiCommandClickHandlers; import org.ovirt.engine.ui.common.widget.HasValidation; import org.ovirt.engine.ui.common.widget.LeftAlignedUiCommandButton; import org.ovirt.engine.ui.common.widget.dialog.tab.DialogTab; @@ -89,4 +90,9 @@ public Map<TabName, DialogTab> getTabNameMapping() { return ((AbstractVmPopupWidget) getContentWidget()).getTabNameMapping(); } + + @Override + public HasUiCommandClickHandlers getNumaSupportButton() { + return ((AbstractVmPopupWidget) getContentWidget()).getNumaSupportButton(); + } } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/DraggableVirtualNumaPanel.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/DraggableVirtualNumaPanel.java index 65fe387..caf0b61 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/DraggableVirtualNumaPanel.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/view/popup/numa/DraggableVirtualNumaPanel.java @@ -70,6 +70,8 @@ private HandlerRegistration contextMenuHandlerRegistration; private MenuBar menuBar; + private boolean dragEnabled; + @Inject public DraggableVirtualNumaPanel(EventBus gwtEventBus, CommonApplicationResources commonResources, CommonApplicationMessages messages, CommonApplicationConstants commonConstants, @@ -86,6 +88,9 @@ @Override public void onLoad() { super.onLoad(); + if (!dragEnabled) { + return; + } contextMenuHandlerRegistration = numaPanel.addDomHandler(new ContextMenuHandler() { @Override public void onContextMenu(ContextMenuEvent event) { @@ -100,6 +105,9 @@ @Override public void onUnload() { super.onUnload(); + if (!dragEnabled) { + return; + } contextMenuHandlerRegistration.removeHandler(); } @@ -112,18 +120,27 @@ @UiHandler("container") void handleMouseOver(MouseOverEvent event) { + if (!dragEnabled) { + return; + } container.addStyleName(style.panelOver()); dragHandle.setVisible(true); } @UiHandler("container") void handleMouseOut(MouseOutEvent event) { + if (!dragEnabled) { + return; + } container.removeStyleName(style.panelOver()); dragHandle.setVisible(false); } @UiHandler("container") void onDragStart(DragStartEvent event) { + if (!dragEnabled) { + return; + } event.setData("VM_GID", nodeModel.getVm().getId().toString()); //$NON-NLS-1$ event.setData("PINNED", String.valueOf(nodeModel.isPinned())); //$NON-NLS-1$ event.setData("INDEX", String.valueOf(nodeModel.getVmNumaNode().getIndex())); //$NON-NLS-1$ @@ -147,10 +164,13 @@ /** * Dragging is enabled by default, if you want to alter that behavior, call this method with false. - * @param enable Enabled or disable dragging of this panel. + * + * @param dragEnabled + * Enabled or disable dragging of this panel. */ - public void enableDrag(boolean enable) { - if (enable) { + public void enableDrag(boolean dragEnabled) { + this.dragEnabled = dragEnabled; + if (dragEnabled) { getElement().setDraggable(Element.DRAGGABLE_TRUE); } else { getElement().setDraggable(Element.DRAGGABLE_FALSE); @@ -165,7 +185,11 @@ public void setModel(VNodeModel nodeModel, List<VdsNumaNode> numaNodeList) { numaPanel.setModel(nodeModel); this.nodeModel = nodeModel; - createMenu(numaNodeList, nodeModel.getVmNumaNode().getIndex()); + if (nodeModel.isLocked()) { + enableDrag(false); + } else { + createMenu(numaNodeList, nodeModel.getVmNumaNode().getIndex()); + } } private void createMenu(final List<VdsNumaNode> numaNodeList, int indexToSkip) { diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/popup/AbstractVmBasedPopupPresenterWidget.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/popup/AbstractVmBasedPopupPresenterWidget.java index 2bec7bf..25aa70d 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/popup/AbstractVmBasedPopupPresenterWidget.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/popup/AbstractVmBasedPopupPresenterWidget.java @@ -3,19 +3,27 @@ import java.util.List; import org.ovirt.engine.ui.common.presenter.AbstractModelBoundPopupPresenterWidget; +import org.ovirt.engine.ui.common.presenter.popup.numa.NumaSupportPopupPresenterWidget; import org.ovirt.engine.ui.common.system.ClientStorage; import org.ovirt.engine.ui.common.utils.ValidationTabSwitchHelper; import org.ovirt.engine.ui.common.view.TabbedView; +import org.ovirt.engine.ui.common.widget.HasUiCommandClickHandlers; import org.ovirt.engine.ui.common.widget.HasValidation; +import org.ovirt.engine.ui.uicommonweb.UICommand; +import org.ovirt.engine.ui.uicommonweb.models.Model; +import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.NumaSupportModel; import org.ovirt.engine.ui.uicommonweb.models.vms.UnitVmModel; import org.ovirt.engine.ui.uicompat.Event; import org.ovirt.engine.ui.uicompat.EventArgs; import org.ovirt.engine.ui.uicompat.IEventListener; +import com.google.gwt.event.dom.client.ClickEvent; +import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.logical.shared.HasAttachHandlers; import com.google.gwt.event.shared.EventBus; import com.google.gwt.user.client.ui.HasVisibility; import com.google.inject.Inject; +import com.google.inject.Provider; public class AbstractVmBasedPopupPresenterWidget<V extends AbstractVmBasedPopupPresenterWidget.ViewDef> extends AbstractModelBoundPopupPresenterWidget<UnitVmModel, V> { @@ -30,15 +38,26 @@ void switchAttachToInstanceType(boolean isAttached); List<HasValidation> getInvalidWidgets(); + + HasUiCommandClickHandlers getNumaSupportButton(); } private final ClientStorage clientStorage; + private Provider<NumaSupportPopupPresenterWidget> numaSupportProvider; @Inject public AbstractVmBasedPopupPresenterWidget(EventBus eventBus, V view, ClientStorage clientStorage) { super(eventBus, view); this.clientStorage = clientStorage; + } + + public AbstractVmBasedPopupPresenterWidget(EventBus eventBus, + V view, + ClientStorage clientStorage, + Provider<NumaSupportPopupPresenterWidget> numaSupportProvider) { + this(eventBus, view, clientStorage); + this.numaSupportProvider = numaSupportProvider; } @Override @@ -59,6 +78,16 @@ // hide the admin-only widgets only for non-admin users getView().initToCreateInstanceMode(); } + } + + @Override + public AbstractModelBoundPopupPresenterWidget<? extends Model, ?> getModelPopup(UnitVmModel source, + UICommand lastExecutedCommand, + Model windowModel) { + if (windowModel instanceof NumaSupportModel) { + return numaSupportProvider.get(); + } + return super.getModelPopup(source, lastExecutedCommand, windowModel); } @Override @@ -93,6 +122,13 @@ } }); + + registerHandler(getView().getNumaSupportButton().addClickHandler(new ClickHandler() { + @Override + public void onClick(ClickEvent event) { + getView().getNumaSupportButton().getCommand().execute(); + } + })); } private void switchToAdvancedIfNeeded(final UnitVmModel model) { diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java index 2ccc975..8cbf5db 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java @@ -17,6 +17,7 @@ import org.ovirt.engine.core.common.businessentities.ImageStatus; import org.ovirt.engine.core.common.businessentities.InstanceType; import org.ovirt.engine.core.common.businessentities.MigrationSupport; +import org.ovirt.engine.core.common.businessentities.NumaTuneMode; import org.ovirt.engine.core.common.businessentities.Quota; import org.ovirt.engine.core.common.businessentities.UsbPolicy; import org.ovirt.engine.core.common.businessentities.VDS; @@ -42,6 +43,7 @@ import org.ovirt.engine.ui.common.widget.EntityModelWidgetWithInfo; import org.ovirt.engine.ui.common.widget.HasDetachable; import org.ovirt.engine.ui.common.widget.HasValidation; +import org.ovirt.engine.ui.common.widget.UiCommandButton; import org.ovirt.engine.ui.common.widget.dialog.AdvancedParametersExpander; import org.ovirt.engine.ui.common.widget.dialog.InfoIcon; import org.ovirt.engine.ui.common.widget.dialog.tab.DialogTab; @@ -564,6 +566,19 @@ @Path(value = "hostCpu.entity") @WithElementId("hostCpu") public EntityModelCheckBoxEditor hostCpuEditor; + + @UiField + @Path(value = "numaNodeCount.entity") + @WithElementId("numaNodeCount") + public IntegerEntityModelTextBoxEditor numaNodeCount; + + @UiField(provided = true) + @Path(value = "numaTuneMode.selectedItem") + @WithElementId("numaTuneMode") + public ListModelListBoxEditor<NumaTuneMode> numaTuneMode; + + @UiField + UiCommandButton numaSupportButton; @Path(value = "migrationMode.selectedItem") @WithElementId("migrationMode") @@ -1283,6 +1298,8 @@ cpuSharesAmountSelectionEditor = new ListModelListBoxOnlyEditor<UnitVmModel.CpuSharesAmount>(new EnumRenderer(), new ModeSwitchingVisibilityRenderer()); + + numaTuneMode = new ListModelListBoxEditor<NumaTuneMode>(new EnumRenderer(), new ModeSwitchingVisibilityRenderer()); } private String typeAheadNameDescriptionTemplateNullSafe(String name, String description) { @@ -1370,6 +1387,9 @@ hostCpuEditor.setLabel(constants.useHostCpu()); cpuPinning.setLabel(constants.cpuPinningLabel()); + // numa + numaTuneMode.setLabel(constants.numaTunaModeLabel()); + numaNodeCount.setLabel(constants.numaNodeCountLabel()); // High Availability Tab isHighlyAvailableEditor.setLabel(constants.highlyAvailableVmPopup()); @@ -1430,6 +1450,7 @@ initListeners(model); hideAlwaysHiddenFields(); decorateDetachableFields(); + numaSupportButton.setCommand(model.getNumaSupportCommand()); } @UiHandler("refreshButton") @@ -1843,6 +1864,8 @@ migrationDowntimeEditor.setTabIndex(nextTabIndex++); hostCpuEditor.setTabIndex(nextTabIndex++); + numaNodeCount.setTabIndex(nextTabIndex++); + numaTuneMode.setTabIndex(nextTabIndex++); // ==High Availability Tab== nextTabIndex = highAvailabilityTab.setTabIndexes(nextTabIndex); isHighlyAvailableEditor.setTabIndex(nextTabIndex++); @@ -2116,4 +2139,8 @@ public Map<TabName, DialogTab> getTabNameMapping() { return tabMap; } + + public UiCommandButton getNumaSupportButton() { + return numaSupportButton; + } } diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml index b9bff79..d50e6d1 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml @@ -404,7 +404,9 @@ .detachableStyle { display: inline-block; } - + .button { + padding: 0 5px; + } </ui:style> <t:DialogTabPanel width="100%" height="100%" ui:field="mainTabPanel"> @@ -606,6 +608,9 @@ <ge:IntegerEntityModelTextBoxOnlyEditor ui:field="migrationDowntimeEditor" addStyleNames="{style.migrationDowntime}" /> </g:FlowPanel> <ge:EntityModelCheckBoxEditor ui:field="hostCpuEditor" addStyleNames="{style.checkbox}"/> + <ge:IntegerEntityModelTextBoxEditor ui:field="numaNodeCount" /> + <e:ListModelListBoxEditor ui:field="numaTuneMode" /> + <w:UiCommandButton ui:field="numaSupportButton" addStyleNames="{style.button}"/> </g:VerticalPanel> </g:FlowPanel> </t:content> diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonUnitToVmBaseBuilder.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonUnitToVmBaseBuilder.java index 2213c21..69e5551 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonUnitToVmBaseBuilder.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonUnitToVmBaseBuilder.java @@ -16,7 +16,8 @@ super( new CoreUnitToVmBaseBuilder(), new QuotaUnitToVmBaseBuilder<T>(), - new CpuProfileUnitToVmBaseBuilder<T>() + new CpuProfileUnitToVmBaseBuilder<T>(), + new NumaUnitToVmBaseBuilder<T>() ); } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonVmBaseToUnitBuilder.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonVmBaseToUnitBuilder.java index 729d144..21da2f2 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonVmBaseToUnitBuilder.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/CommonVmBaseToUnitBuilder.java @@ -19,5 +19,6 @@ model.getAllowConsoleReconnect().setEntity(vm.isAllowConsoleReconnect()); model.getIsStateless().setEntity(vm.isStateless()); model.getIsRunAndPause().setEntity(vm.isRunAndPause()); + model.getNumaTuneMode().setSelectedItem(vm.getNumaTuneMode()); } } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java new file mode 100644 index 0000000..0509641 --- /dev/null +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/NumaUnitToVmBaseBuilder.java @@ -0,0 +1,51 @@ +package org.ovirt.engine.ui.uicommonweb.builders.vm; + +import java.util.ArrayList; +import java.util.List; + +import org.ovirt.engine.core.common.businessentities.VmBase; +import org.ovirt.engine.core.common.businessentities.VmNumaNode; +import org.ovirt.engine.core.common.utils.Pair; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.ui.uicommonweb.builders.BaseSyncBuilder; +import org.ovirt.engine.ui.uicommonweb.models.vms.UnitVmModel; + +public class NumaUnitToVmBaseBuilder<T extends VmBase> extends BaseSyncBuilder<UnitVmModel, T> { + + @Override + protected void build(UnitVmModel model, VmBase vm) { + Integer nodeCount = model.getNumaNodeCount().getEntity(); + // clear NUMA nodes + if (nodeCount == null || nodeCount == 0) { + vm.setvNumaNodeList(null); + } else { + // no change in NUMA nodes + if (model.getVmNumaNodes() != null && nodeCount == model.getVmNumaNodes().size()) { + vm.setvNumaNodeList(model.getVmNumaNodes()); + // create numa nodes + } else { + List<VmNumaNode> nodeList = new ArrayList<VmNumaNode>(nodeCount); + Integer coresPerNode = Integer.parseInt(model.getTotalCPUCores().getEntity()) / nodeCount; + int coreIndex = 0; + for (int i = 0; i < nodeCount; i++) { + VmNumaNode vmNumaNode = new VmNumaNode(); + vmNumaNode.setIndex(i); + // divide memory for each numa node + vmNumaNode.setMemTotal(model.getMemSize().getEntity() / nodeCount); + vmNumaNode.setVdsNumaNodeList(new ArrayList<Pair<Guid, Pair<Boolean, Integer>>>()); + Pair<Guid, Pair<Boolean, Integer>> pair = new Pair<Guid, Pair<Boolean, Integer>>(); + pair.setSecond(new Pair<Boolean, Integer>(false, i)); + vmNumaNode.getVdsNumaNodeList().add(pair); + List<Integer> coreList = new ArrayList<Integer>(); + for (int j = 0; j < coresPerNode; j++, coreIndex++) { + coreList.add(coreIndex); + } + vmNumaNode.setCpuIds(coreList); + nodeList.add(vmNumaNode); + } + vm.setvNumaNodeList(nodeList); + } + } + vm.setNumaTuneMode(model.getNumaTuneMode().getSelectedItem()); + } +} diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java index c5d3a57..b54f173 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/NumaSupportModel.java @@ -38,7 +38,7 @@ private List<VdsNumaNode> numaNodeList; private List<VM> vmsWithvNumaNodeList; private List<VNodeModel> unassignedVNodeModelList; - private Map<Guid, List<VNodeModel>> p2vNumaNodesMap; + protected Map<Guid, List<VNodeModel>> p2vNumaNodesMap; private List<Pair<Integer, Set<VdsNumaNode>>> firstLevelDistanceSetList; private final Event modelReady = new Event(new EventDefinition("ModelReady", NumaSupportModel.class)); //$NON-NLS-1$ private Map<Integer, VdsNumaNode> indexNodeMap; @@ -109,7 +109,7 @@ }), hosts.getSelectedItem().getId()); } - private void initVNumaNodes() { + protected void initVNumaNodes() { unassignedVNodeModelList = new ArrayList<VNodeModel>(); p2vNumaNodesMap = new HashMap<Guid, List<VNodeModel>>(); diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java index dbf3909..edabeac 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VNodeModel.java @@ -9,6 +9,7 @@ private final VM vm; private final VmNumaNode vmNumaNode; private boolean pinned; + private boolean locked; public VNodeModel(NumaSupportModel numaSupportModel, VM vm, VmNumaNode vmNumaNode, boolean pinned) { this.numaSupportModel = numaSupportModel; @@ -40,4 +41,12 @@ public boolean isSplitted() { return getVmNumaNode().getVdsNumaNodeList() != null && getVmNumaNode().getVdsNumaNodeList().size() > 1; } + + public void setLocked(boolean locked) { + this.locked = locked; + } + + public boolean isLocked() { + return locked; + } } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VmNumaSupportModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VmNumaSupportModel.java new file mode 100644 index 0000000..3a3e1cc --- /dev/null +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/hosts/numa/VmNumaSupportModel.java @@ -0,0 +1,62 @@ +package org.ovirt.engine.ui.uicommonweb.models.hosts.numa; + +import java.util.List; + +import org.ovirt.engine.core.common.businessentities.VDS; +import org.ovirt.engine.core.common.businessentities.VM; +import org.ovirt.engine.core.compat.Guid; +import org.ovirt.engine.ui.uicommonweb.models.Model; + +public class VmNumaSupportModel extends NumaSupportModel { + + private final VM vm; + + public VmNumaSupportModel(List<VDS> hosts, VDS host, Model parentModel, VM vm) { + super(hosts, host, parentModel); + this.vm = vm; + } + + @Override + public void setVmsWithvNumaNodeList(List<VM> vmsWithvNumaNodeList) { + if (Guid.isNullOrEmpty(vm.getId())) { + vmsWithvNumaNodeList.add(vm); + } else { + VM removeVm = null; + for (VM inerVm : vmsWithvNumaNodeList) { + if (inerVm.getId().equals(vm.getId())) { + removeVm = inerVm; + break; + } + } + vmsWithvNumaNodeList.remove(removeVm); + vmsWithvNumaNodeList.add(vm); + } + super.setVmsWithvNumaNodeList(vmsWithvNumaNodeList); + } + + @Override + protected void initVNumaNodes() { + super.initVNumaNodes(); + lockOtherVmNodes(); + } + + private void lockOtherVmNodes() { + for (VNodeModel nodeModel : getUnassignedVNodeModelList()) { + if (!nodeModel.getVm().getId().equals(vm.getId())) { + nodeModel.setLocked(true); + } + } + + for (List<VNodeModel> list : p2vNumaNodesMap.values()) { + for (VNodeModel nodeModel : list) { + if (!nodeModel.getVm().getId().equals(vm.getId())) { + nodeModel.setLocked(true); + } + } + } + } + + public VM getVm() { + return vm; + } +} diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java index 45deac4..33d7bde 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java @@ -11,11 +11,16 @@ import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VMStatus; import org.ovirt.engine.core.common.businessentities.VmBase; +import org.ovirt.engine.core.common.businessentities.VmNumaNode; import org.ovirt.engine.core.common.queries.ConfigurationValues; +import org.ovirt.engine.core.common.queries.IdQueryParameters; +import org.ovirt.engine.core.common.queries.VdcQueryReturnValue; +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.core.compat.Version; import org.ovirt.engine.ui.frontend.AsyncQuery; +import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.frontend.INewAsyncCallback; import org.ovirt.engine.ui.uicommonweb.builders.BuilderExecutor; import org.ovirt.engine.ui.uicommonweb.builders.vm.CommentVmBaseToUnitBuilder; @@ -64,6 +69,19 @@ if (vm.getVmPoolId() != null) { instanceTypeManager.setAlwaysEnabledFieldUpdate(true); } + + Frontend.getInstance().runQuery(VdcQueryType.GetVmNumaNodesByVmId, + new IdQueryParameters(vm.getId()), + new AsyncQuery(new INewAsyncCallback() { + + @Override + public void onSuccess(Object model, Object returnValue) { + List<VmNumaNode> nodes = + (List<VmNumaNode>) ((VdcQueryReturnValue) returnValue).getReturnValue(); + ExistingVmModelBehavior.this.getModel().setVmNumaNodes(nodes); + ExistingVmModelBehavior.this.getModel().getNumaNodeCount().setEntity(nodes.size()); + } + })); } private void loadDataCenter() { @@ -253,7 +271,7 @@ { double overCommitFactor = 100.0 / cluster.getmax_vds_memory_over_commit(); getModel().getMinAllocatedMemory() - .setEntity((int) ((Integer) getModel().getMemSize().getEntity() * overCommitFactor)); + .setEntity((int) (getModel().getMemSize().getEntity() * overCommitFactor)); } else { @@ -353,4 +371,16 @@ public ExistingVmInstanceTypeManager getInstanceTypeManager() { return (ExistingVmInstanceTypeManager) instanceTypeManager; } + + @Override + protected VM getVmWithNuma() { + VM dummyVm = super.getVmWithNuma(); + dummyVm.setId(vm.getId()); + List<VmNumaNode> vmNumaNodes = getModel().getVmNumaNodes(); + if (vmNumaNodes != null && !vmNumaNodes.isEmpty() && vmNumaNodes.size() == dummyVm.getvNumaNodeList().size()) { + dummyVm.setvNumaNodeList(vmNumaNodes); + } + + return dummyVm; + } } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java index f58e71d..74ce7d0 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java @@ -14,6 +14,7 @@ import org.ovirt.engine.core.common.businessentities.DisplayType; import org.ovirt.engine.core.common.businessentities.InstanceType; import org.ovirt.engine.core.common.businessentities.MigrationSupport; +import org.ovirt.engine.core.common.businessentities.NumaTuneMode; import org.ovirt.engine.core.common.businessentities.Quota; import org.ovirt.engine.core.common.businessentities.QuotaEnforcementTypeEnum; import org.ovirt.engine.core.common.businessentities.SerialNumberPolicy; @@ -23,6 +24,7 @@ import org.ovirt.engine.core.common.businessentities.UsbPolicy; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.businessentities.VmNumaNode; import org.ovirt.engine.core.common.businessentities.VmPoolType; import org.ovirt.engine.core.common.businessentities.VmRngDevice; import org.ovirt.engine.core.common.businessentities.VmTemplate; @@ -40,8 +42,10 @@ import org.ovirt.engine.ui.frontend.AsyncQuery; import org.ovirt.engine.ui.frontend.Frontend; import org.ovirt.engine.ui.frontend.INewAsyncCallback; +import org.ovirt.engine.ui.uicommonweb.ICommandTarget; import org.ovirt.engine.ui.uicommonweb.Linq; import org.ovirt.engine.ui.uicommonweb.TypeResolver; +import org.ovirt.engine.ui.uicommonweb.UICommand; import org.ovirt.engine.ui.uicommonweb.auth.CurrentUserRole; import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider; import org.ovirt.engine.ui.uicommonweb.models.EntityModel; @@ -52,6 +56,8 @@ import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemType; import org.ovirt.engine.ui.uicommonweb.models.TabName; import org.ovirt.engine.ui.uicommonweb.models.ValidationCompleteEvent; +import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.NumaSupportModel; +import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.VmNumaSupportModel; import org.ovirt.engine.ui.uicommonweb.models.storage.DisksAllocationModel; import org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager; import org.ovirt.engine.ui.uicommonweb.models.vms.key_value.KeyValueModel; @@ -1290,6 +1296,48 @@ this.cpuProfiles = cpuProfiles; } + private EntityModel<Boolean> numaEnabled; + + private NotChangableForVmInPoolListModel<NumaTuneMode> numaTuneMode; + + public ListModel<NumaTuneMode> getNumaTuneMode() { + return numaTuneMode; + } + + public void setNumaTuneMode(NotChangableForVmInPoolListModel<NumaTuneMode> numaTuneMode) { + this.numaTuneMode = numaTuneMode; + } + + private NotChangableForVmInPoolEntityModel<Integer> numaNodeCount; + + public EntityModel<Integer> getNumaNodeCount() { + return numaNodeCount; + } + + public void setNumaNodeCount(NotChangableForVmInPoolEntityModel<Integer> numaNodeCount) { + this.numaNodeCount = numaNodeCount; + } + + private List<VmNumaNode> vmNumaNodes; + + public List<VmNumaNode> getVmNumaNodes() { + return vmNumaNodes; + } + + public void setVmNumaNodes(List<VmNumaNode> vmNumaNodes) { + this.vmNumaNodes = vmNumaNodes; + } + + private UICommand numaSupportCommand; + + public UICommand getNumaSupportCommand() { + return numaSupportCommand; + } + + private void setNumaSupportCommand(UICommand numaSupportCommand) { + this.numaSupportCommand = numaSupportCommand; + } + public UnitVmModel(VmModelBehaviorBase behavior) { Frontend.getInstance().getQueryStartedEvent().addListener(this); Frontend.getInstance().getQueryCompleteEvent().addListener(this); @@ -1545,6 +1593,27 @@ setCpuProfiles(new NotChangableForVmInPoolListModel<CpuProfile>()); getCpuProfiles().setIsAvailable(false); + + setNumaTuneMode(new NotChangableForVmInPoolListModel<NumaTuneMode>()); + getNumaTuneMode().setItems(AsyncDataProvider.getInstance().getNumaTuneModeList()); + getNumaTuneMode().setSelectedItem(NumaTuneMode.INTERLEAVE); + + setNumaNodeCount(new NotChangableForVmInPoolEntityModel<Integer>()); + getNumaNodeCount().setEntity(0); + setNumaEnabled(new EntityModel<Boolean>()); + getNumaEnabled().setEntity(false); + + setNumaSupportCommand(new UICommand("NumaSupport", new ICommandTarget() { //$NON-NLS-1$ + @Override + public void executeCommand(UICommand command) { + numaSupport(); + } + + @Override + public void executeCommand(UICommand uiCommand, Object... parameters) { + numaSupport(); + } + })); } public void initialize(SystemTreeItemModel SystemTreeSelectedItem) @@ -2894,4 +2963,32 @@ return ((CurrentUserRole) TypeResolver.getInstance().resolve(CurrentUserRole.class)).isCreateInstanceOnly(); } + private void numaSupport() { + getBehavior().numaSupport(); + } + + public EntityModel<Boolean> getNumaEnabled() { + return numaEnabled; + } + + public void setNumaEnabled(EntityModel<Boolean> numaEnabled) { + this.numaEnabled = numaEnabled; + } + + @Override + public void executeCommand(UICommand command) { + super.executeCommand(command); + + if (NumaSupportModel.SUBMIT_NUMA_SUPPORT.equals(command.getName())) { + onNumaSupport(); + } + } + + private void onNumaSupport() { + if (getWindow() == null) { + return; + } + VmNumaSupportModel model = (VmNumaSupportModel) getWindow(); + setVmNumaNodes(model.getVm().getvNumaNodeList()); + } } diff --git a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java index 9ed8c4b..f4023c7 100644 --- a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java +++ b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java @@ -23,7 +23,9 @@ import org.ovirt.engine.core.common.businessentities.StoragePool; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VDSGroup; +import org.ovirt.engine.core.common.businessentities.VM; import org.ovirt.engine.core.common.businessentities.VmBase; +import org.ovirt.engine.core.common.businessentities.VmNumaNode; import org.ovirt.engine.core.common.businessentities.VmRngDevice; import org.ovirt.engine.core.common.businessentities.VmTemplate; import org.ovirt.engine.core.common.businessentities.VmType; @@ -46,6 +48,8 @@ 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.hosts.numa.NumaSupportModel; +import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.VmNumaSupportModel; import org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager; import org.ovirt.engine.ui.uicompat.ConstantsManager; import org.ovirt.engine.ui.uicompat.UIConstants; @@ -1220,4 +1224,33 @@ } })); } + + public void numaSupport() { + if (getModel().getWindow() != null) { + return; + } + VM vm = getVmWithNuma(); + NumaSupportModel model = + new VmNumaSupportModel((List<VDS>) getModel().getDefaultHost().getItems(), getModel().getDefaultHost() + .getSelectedItem(), getModel(), vm); + + getModel().setWindow(model); + } + + protected VM getVmWithNuma() { + VM vm = new VM(); + String vmName = getModel().getName().getEntity(); + if (vmName == null || vmName.isEmpty()) { + vmName = "new_vm"; //$NON-NLS-1$ + } + vm.setName(vmName); + Integer nodeCount = getModel().getNumaNodeCount().getEntity(); + vm.setvNumaNodeList(new ArrayList<VmNumaNode>()); + for (int i = 0; i < nodeCount; i++) { + VmNumaNode vmNumaNode = new VmNumaNode(); + vmNumaNode.setIndex(i); + vm.getvNumaNodeList().add(vmNumaNode); + } + return vm; + } } diff --git a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java index 8809293..6e15935 100644 --- a/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java +++ b/frontend/webadmin/modules/uicompat/src/main/java/org/ovirt/engine/ui/uicompat/LocalizedEnums.java @@ -1,5 +1,7 @@ package org.ovirt.engine.ui.uicompat; +import org.ovirt.engine.core.common.businessentities.NumaTuneMode; + import com.google.gwt.i18n.client.ConstantsWithLookup; public interface LocalizedEnums extends ConstantsWithLookup { @@ -961,4 +963,10 @@ String ActionGroup___DELETE_MAC_POOL(); String ActionGroup___CONFIGURE_MAC_POOL(); + + String NumaTuneMode___STRICT(); + + String NumaTuneMode___PREFERRED(); + + String NumaTuneMode___INTERLEAVE(); } diff --git a/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties b/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties index 544a637..301d856 100644 --- a/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties +++ b/frontend/webadmin/modules/uicompat/src/main/resources/org/ovirt/engine/ui/uicompat/LocalizedEnums.properties @@ -479,3 +479,6 @@ SELinuxMode___ENFORCING=Enforcing SELinuxMode___PERMISSIVE=Permissive SELinuxMode___DISABLED=Disabled +NumaTuneMode___STRICT=Strict +NumaTuneMode___PREFERRED=Preferred +NumaTuneMode___INTERLEAVE=Interleave diff --git a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/vm/VmPopupPresenterWidget.java b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/vm/VmPopupPresenterWidget.java index ac994ef..3aaa74e 100644 --- a/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/vm/VmPopupPresenterWidget.java +++ b/frontend/webadmin/modules/webadmin/src/main/java/org/ovirt/engine/ui/webadmin/section/main/presenter/popup/vm/VmPopupPresenterWidget.java @@ -1,10 +1,12 @@ package org.ovirt.engine.ui.webadmin.section.main.presenter.popup.vm; +import org.ovirt.engine.ui.common.presenter.popup.numa.NumaSupportPopupPresenterWidget; import org.ovirt.engine.ui.common.system.ClientStorage; import org.ovirt.engine.ui.common.widget.popup.AbstractVmBasedPopupPresenterWidget; import com.google.gwt.event.shared.EventBus; import com.google.inject.Inject; +import com.google.inject.Provider; public class VmPopupPresenterWidget extends AbstractVmBasedPopupPresenterWidget<VmPopupPresenterWidget.ViewDef> { @@ -13,7 +15,8 @@ } @Inject - public VmPopupPresenterWidget(EventBus eventBus, ViewDef view, ClientStorage clientStorage) { - super(eventBus, view, clientStorage); + public VmPopupPresenterWidget(EventBus eventBus, ViewDef view, ClientStorage clientStorage, + Provider<NumaSupportPopupPresenterWidget> numaSupportProvider) { + super(eventBus, view, clientStorage, numaSupportProvider); } } -- To view, visit http://gerrit.ovirt.org/32913 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I05b83028b722088e39ad7156c77ad4eb479dc241 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: master Gerrit-Owner: Gilad Chaplik <gchap...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches