Roy Golan has uploaded a new change for review. Change subject: UI: hot set number of CPU when updating a VM ......................................................................
UI: hot set number of CPU when updating a VM * allow updating the number of sockets of a runing VM * disable number of cores per sockets change * disable total number of cpus change * added a icon which explains about the action taken when changing the * values. Any change to the socket field will recalculate the total CPUs. This means we add/remove whole sockets from a VM. Changing the topology, i.e. the number of CPUs per socket is not allowed as it can not be reflected in a live OS. Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1036777 Change-Id: Ieac0e757c54b002eeab8f9099e6e8d151eb43340 Signed-off-by: Roy Golan <[email protected]> --- M frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java M frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationMessages.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/models/vms/ExistingVmModelBehavior.java M frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java M frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties M frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties 8 files changed, 122 insertions(+), 13 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/78/23478/1 diff --git a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java index 7a22338..2612f1b 100644 --- a/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java +++ b/frontend/webadmin/modules/frontend/src/main/java/org/ovirt/engine/ui/frontend/AppErrors.java @@ -856,6 +856,9 @@ @DefaultStringValue("$action hot unplug") String VAR__ACTION__HOT_UNPLUG(); + @DefaultStringValue("$action hot set cpus") + String VAR__ACTION__HOT_SET_CPUS(); + @DefaultStringValue("$action log on") String VAR__ACTION__LOGON(); diff --git a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationMessages.java b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationMessages.java index abde869..290789c 100644 --- a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationMessages.java +++ b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationMessages.java @@ -144,4 +144,7 @@ @DefaultMessage("{0} or {1}") String or(String a, String b); + @DefaultMessage("Hot set CPUs by changing the number of sockets." + + " The support for hot plug/unplug CPUs to the guest varies.") + String hotPlugUnplugCpuWarning(); } 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 91765fa..572d2e1 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 @@ -213,7 +213,10 @@ @UiField(provided = true) @Path(value = "totalCPUCores.entity") @WithElementId("totalCPUCores") - public EntityModelTextBoxEditor<String> totalvCPUsEditor; + public StringEntityModelTextBoxOnlyEditor totalvCPUsEditor; + + @UiField(provided = true) + InfoIcon totalVCpuInfoIcon; @UiField @Ignore @@ -735,7 +738,7 @@ private void initTextBoxEditors() { descriptionEditor = new StringEntityModelTextBoxEditor(new ModeSwitchingVisibilityRenderer()); commentEditor = new StringEntityModelTextBoxEditor(new ModeSwitchingVisibilityRenderer()); - totalvCPUsEditor = new StringEntityModelTextBoxEditor(new ModeSwitchingVisibilityRenderer()); + totalvCPUsEditor = new StringEntityModelTextBoxOnlyEditor(new ModeSwitchingVisibilityRenderer()); numOfVmsEditor = new IntegerEntityModelTextBoxEditor(new ModeSwitchingVisibilityRenderer()); cpuPinning = new StringEntityModelTextBoxOnlyEditor(new ModeSwitchingVisibilityRenderer()); cpuSharesAmountEditor = new IntegerEntityModelTextBoxOnlyEditor(new ModeSwitchingVisibilityRenderer()); @@ -779,6 +782,8 @@ } }); + + totalVCpuInfoIcon = new InfoIcon(applicationTemplates.italicText(messages.hotPlugUnplugCpuWarning()), resources); } /** @@ -1055,7 +1060,6 @@ // System tab memSizeEditor.setLabel(constants.memSizeVmPopup()); - totalvCPUsEditor.setLabel(constants.numOfVCPUs()); corePerSocketEditor.setLabel(constants.coresPerSocket()); numOfSocketsEditor.setLabel(constants.numOfSockets()); } 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 c636bc9..d748b74 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 @@ -304,6 +304,10 @@ padding-left: 5px; } + .totalvcpusTextBox { + float: right; + } + .cpuSahresValueTextBox { padding-left: 5px; } @@ -405,8 +409,12 @@ <t:DialogTab ui:field="systemTab"> <t:content> <g:FlowPanel> - <ge:EntityModelTextBoxEditor ui:field="memSizeEditor"/> - <ge:EntityModelTextBoxEditor ui:field="totalvCPUsEditor" /> + <ge:EntityModelTextBoxEditor ui:field="memSizeEditor"/> + <g:FlowPanel addStyleNames="{style.labelToCouple}"> + <g:Label text="{constants.numOfVCPUs}" addStyleNames="{style.labelToCoupleLabel}"/> + <d:InfoIcon ui:field="totalVCpuInfoIcon"/> + <ge:StringEntityModelTextBoxOnlyEditor ui:field="totalvCPUsEditor" addStyleNames="{style.totalvcpusTextBox}"/> + </g:FlowPanel> <g:FlowPanel addStyleNames="{style.sectionPanel}"> <d:AdvancedParametersExpander ui:field="vcpusAdvancedParameterExpander"/> <g:FlowPanel ui:field="vcpusAdvancedParameterExpanderContent" addStyleNames="{style.generalExpanderContent}"> 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 ea081fe..a3a9c95 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 @@ -4,18 +4,23 @@ import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Map; import org.ovirt.engine.core.common.businessentities.DisplayType; 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.VMStatus; import org.ovirt.engine.core.common.businessentities.VmWatchdog; import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface; +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; @@ -32,6 +37,8 @@ protected VM vm; private List<VmNetworkInterface> networkInerfaces; + private int hostCpu; + private VDS runningOnHost; public ExistingVmModelBehavior(VM vm) { @@ -179,7 +186,7 @@ getModel().selectSsoMethod(vm.getSsoMethod()); getModel().getNumOfSockets().setSelectedItem(vm.getNumOfSockets()); - getModel().getNumOfSockets().setIsChangable(!vm.isRunning()); + getModel().getNumOfSockets().setIsChangable(isHotSetCpuSupported() || !vm.isRunning()); getModel().getCoresPerSocket().setIsChangable(!vm.isRunning()); @@ -262,6 +269,27 @@ getModel().getCpuPinning().setEntity(vm.getCpuPinning()); initPriority(vm.getPriority()); + + if (isHotSetCpuSupported()) { + // cancel related events while fetching data + getModel().getTotalCPUCores().getEntityChangedEvent().removeListener(getModel()); + getModel().getCoresPerSocket().getSelectedItemChangedEvent().removeListener(getModel()); + getModel().getNumOfSockets().getSelectedItemChangedEvent().removeListener(getModel()); + + AsyncDataProvider.getHostById(new AsyncQuery(this, new INewAsyncCallback() { + @Override + public void onSuccess(Object model, Object returnValue) { + ExistingVmModelBehavior existingVmModelBehavior = (ExistingVmModelBehavior) model; + runningOnHost = (VDS) returnValue; + hostCpu = calculateHostCpus(); + existingVmModelBehavior.updateNumOfSockets(); + } + }), vm.getRunOnVds()); + } + } + + private int calculateHostCpus() { + return getModel().getSelectedCluster().getCountThreadsAsCores() ? runningOnHost.getCpuThreads() : runningOnHost.getCpuCores(); } @Override @@ -339,4 +367,68 @@ updateCdImage(); } + + @Override + public void numOfSocketChanged() { + if (isHotSetCpuSupported()) { + int numOfSockets = extractIntFromListModel(getModel().getNumOfSockets()); + int coresPerSocket = vm.getCpuPerSocket(); + getModel().getTotalCPUCores().setEntity(Integer.toString(numOfSockets * coresPerSocket)); + } else { + super.numOfSocketChanged(); + } + } + + @Override + public void totalCpuCoresChanged() { + if (isHotSetCpuSupported()) { + if (runningOnHost == null) { + return; //async call didn't return with the host yet + } + // must not change the num of cpu per socket so the list has only 1 item + List<Integer> coresPerSockets = Arrays.asList(new Integer[]{vm.getCpuPerSocket()}); + + getModel().getCoresPerSocket().setItems(coresPerSockets); + getModel().getNumOfSockets().setItems(createSocketsRange()); + + getModel().getCoresPerSocket().setSelectedItem(vm.getCpuPerSocket()); + getModel().getNumOfSockets().setSelectedItem(vm.getNumOfSockets()); + + getModel().getNumOfSockets().getSelectedItemChangedEvent().addListener(getModel()); + numOfSocketChanged(); + } else { + super.totalCpuCoresChanged(); + } + } + + /** + * span a list of all possible sockets values + */ + private List<Integer> createSocketsRange() { + List<Integer> res = new ArrayList<Integer>(); + int maxHostCpu = getHostCpu(); + int cpusPerSockets = vm.getCpuPerSocket(); + + for (int i = 1; i <= maxHostCpu; i++) { + // sockets stepping must not exceed the host maximum + if (i * cpusPerSockets <= maxHostCpu) { + res.add(i); + } + } + return res; + } + + public boolean isHotSetCpuSupported() { + VDSGroup selectedCluster = getModel().getSelectedCluster(); + Version clusterVersion = selectedCluster.getcompatibility_version(); + Boolean hotplugEnabled = (Boolean) AsyncDataProvider.getConfigValuePreConverted(ConfigurationValues.HotPlugEnabled, clusterVersion.getValue()); + boolean hotplugCpuSupported = Boolean.parseBoolean(((Map<String, String>) AsyncDataProvider.getConfigValuePreConverted(ConfigurationValues.HotPlugCpuSupported, + clusterVersion.getValue())).get(selectedCluster.getArchitecture().name())); + + return getVm().getStatus() == VMStatus.Up && hotplugEnabled && hotplugCpuSupported; + } + + public int getHostCpu() { + return hostCpu; + } } 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 99458e4..1c5b0db 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 @@ -894,8 +894,6 @@ if (numOfSockets == 0 || coresPerSocket == 0) { initListToOne(getModel().getCoresPerSocket()); initListToOne(getModel().getNumOfSockets()); - coresPerSocket = 1; - numOfSockets = 1; } List<Integer> coresPerSocets = findIndependentPossibleValues(maxCpusPerSocket); @@ -930,7 +928,7 @@ * The hard way of finding, what the correct combination of the sockets and cores/socket should be (e.g. checking * all possible combinations) */ - private void composeCoresAndSocketsWhenDontFitInto(int totalCpuCores) { + protected void composeCoresAndSocketsWhenDontFitInto(int totalCpuCores) { List<Integer> possibleSockets = findIndependentPossibleValues(maxNumOfSockets); List<Integer> possibleCoresPerSocket = findIndependentPossibleValues(maxCpusPerSocket); @@ -957,7 +955,7 @@ } } - private int extractIntFromListModel(ListModel model) { + protected int extractIntFromListModel(ListModel model) { return model.getSelectedItem() != null ? Integer.parseInt(model .getSelectedItem() .toString()) @@ -988,7 +986,6 @@ VmModelBehaviorBase behavior = (VmModelBehaviorBase) array[0]; behavior.maxNumOfSockets = ((Integer) returnValue); behavior.updataMaxVmsInPool(); - } }, getModel().getHash()), version); } @@ -996,7 +993,7 @@ /** * Returns a list of integers which can divide the param */ - private List<Integer> findIndependentPossibleValues(int max) { + protected List<Integer> findIndependentPossibleValues(int max) { List<Integer> res = new ArrayList<Integer>(); int totalCPUCores = getTotalCpuCores(); @@ -1012,7 +1009,7 @@ /** * Filters out the values, which can not be used in conjuction with the others to reach the total CPUs */ - private List<Integer> filterPossibleValues(List<Integer> candidates, List<Integer> others) { + protected List<Integer> filterPossibleValues(List<Integer> candidates, List<Integer> others) { List<Integer> res = new ArrayList<Integer>(); int currentCpusCores = getTotalCpuCores(); diff --git a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index f35790a..0ebf42e 100644 --- a/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/userportal-gwtp/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -302,6 +302,7 @@ VAR__ACTION__DESTROY_DOMAIN=$action destroy VAR__ACTION__HOT_PLUG=$action hot plug VAR__ACTION__HOT_UNPLUG=$action hot unplug +VAR__ACTION__HOT_SET_CPUS=$action hot set cpus VAR__ACTION__LOGON=$action log on VAR__ACTION__LOGOFF=$action log off VAR__ACTION__ASSIGN=$action assign diff --git a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties index fe488f2..41279a4 100644 --- a/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties +++ b/frontend/webadmin/modules/webadmin/src/main/resources/org/ovirt/engine/ui/frontend/AppErrors.properties @@ -317,6 +317,7 @@ VAR__ACTION__DESTROY_DOMAIN=$action destroy VAR__ACTION__HOT_PLUG=$action hot plug VAR__ACTION__HOT_UNPLUG=$action hot unplug +VAR__ACTION__HOT_SET_CPUS=$action hot set cpus VAR__ACTION__LOGON=$action log on VAR__ACTION__LOGOFF=$action log off VAR__ACTION__REBALANCE_START=$action rebalance -- To view, visit http://gerrit.ovirt.org/23478 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ieac0e757c54b002eeab8f9099e6e8d151eb43340 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-engine Gerrit-Branch: ovirt-engine-3.4 Gerrit-Owner: Roy Golan <[email protected]> _______________________________________________ Engine-patches mailing list [email protected] http://lists.ovirt.org/mailman/listinfo/engine-patches
