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

Reply via email to