]> git.proxmox.com Git - pve-manager.git/blobdiff - www/manager6/qemu/ProcessorEdit.js
update shipped appliance info index
[pve-manager.git] / www / manager6 / qemu / ProcessorEdit.js
index b64c70cad5849af92cf7a713fadce30fc6bf14cd..b35387274e00843eb7a15b102b31a34d8116995c 100644 (file)
@@ -1,18 +1,63 @@
+// The view model of the parent shoul contain a 'cgroupMode' variable (or params for v2 are used).
 Ext.define('PVE.qemu.ProcessorInputPanel', {
-    extend: 'PVE.panel.InputPanel',
-    alias: 'widget.PVE.qemu.ProcessorInputPanel',
+    extend: 'Proxmox.panel.InputPanel',
+    alias: 'widget.pveQemuProcessorPanel',
+    onlineHelp: 'qm_cpu',
+
+    insideWizard: false,
+
+    viewModel: {
+       data: {
+           socketCount: 1,
+           coreCount: 1,
+           showCustomModelPermWarning: false,
+           userIsRoot: false,
+       },
+       formulas: {
+           totalCoreCount: get => get('socketCount') * get('coreCount'),
+           cpuunitsDefault: (get) => get('cgroupMode') === 1 ? 1024 : 100,
+           cpuunitsMin: (get) => get('cgroupMode') === 1 ? 2 : 1,
+           cpuunitsMax: (get) => get('cgroupMode') === 1 ? 262144 : 10000,
+       },
+    },
+
+    controller: {
+       xclass: 'Ext.app.ViewController',
+       init: function() {
+           let me = this;
+           let viewModel = me.getViewModel();
+
+           viewModel.set('userIsRoot', Proxmox.UserName === 'root@pam');
+       },
+    },
 
     onGetValues: function(values) {
-       var me = this;
+       let me = this;
+       let cpuunitsDefault = me.getViewModel().get('cpuunitsDefault');
+
+       if (Array.isArray(values.delete)) {
+           values.delete = values.delete.join(',');
+       }
+
+       PVE.Utils.delete_if_default(values, 'cpulimit', '0', me.insideWizard);
+       PVE.Utils.delete_if_default(values, 'cpuunits', `${cpuunitsDefault}`, me.insideWizard);
 
        // build the cpu options:
        me.cpu.cputype = values.cputype;
+
+       if (values.flags) {
+           me.cpu.flags = values.flags;
+       } else {
+           delete me.cpu.flags;
+       }
+
        delete values.cputype;
+       delete values.flags;
        var cpustring = PVE.Parser.printQemuCpu(me.cpu);
 
        // remove cputype delete request:
-       var del = values['delete'];
-       delete values['delete'];
+       var del = values.delete;
+       delete values.delete;
        if (del) {
            del = del.split(',');
            Ext.Array.remove(del, 'cputype');
@@ -28,91 +73,197 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
 
        var delarr = del.join(',');
        if (delarr) {
-           values['delete'] = delarr;
+           values.delete = delarr;
        }
 
        return values;
     },
 
-    initComponent : function() {
-       var me = this;
-
-       me.cpu = {};
-
-       me.column1 = [
-           {
-               xtype: 'numberfield',
-               name: 'sockets',
-               minValue: 1,
-               maxValue: 4,
-               value: '1',
-               fieldLabel: gettext('Sockets'),
-               allowBlank: false,
-               listeners: {
-                   change: function(f, value) {
-                       var sockets = me.down('field[name=sockets]').getValue();
-                       var cores = me.down('field[name=cores]').getValue();
-                       me.down('field[name=totalcores]').setValue(sockets*cores);
-                   }
-               }
-           },
-           {
-               xtype: 'numberfield',
-               name: 'cores',
-               minValue: 1,
-               maxValue: 128,
-               value: '1',
-               fieldLabel: gettext('Cores'),
-               allowBlank: false,
-               listeners: {
-                   change: function(f, value) {
-                       var sockets = me.down('field[name=sockets]').getValue();
-                       var cores = me.down('field[name=cores]').getValue();
-                       me.down('field[name=totalcores]').setValue(sockets*cores);
-                   }
-               }
-           },
-           {
-               xtype: 'pvecheckbox',
-               fieldLabel: gettext('Enable NUMA'),
-               name: 'numa',
-               uncheckedValue: 0
+    setValues: function(values) {
+       let me = this;
+
+       let type = values.cputype;
+       let typeSelector = me.lookupReference('cputype');
+       let typeStore = typeSelector.getStore();
+       typeStore.on('load', (store, records, success) => {
+           if (!success || !type || records.some(x => x.data.name === type)) {
+               return;
            }
 
-       ];
+           // if we get here, a custom CPU model is selected for the VM but we
+           // don't have permission to configure it - it will not be in the
+           // list retrieved from the API, so add it manually to allow changing
+           // other processor options
+           typeStore.add({
+               name: type,
+               displayname: type.replace(/^custom-/, ''),
+               custom: 1,
+               vendor: gettext("Unknown"),
+           });
+           typeSelector.select(type);
+       });
 
+       me.callParent([values]);
+    },
 
-       me.column2 = [
-           {
-               xtype: 'CPUModelSelector',
-               name: 'cputype',
-               value: '__default__',
-               fieldLabel: gettext('Type')
+    cpu: {},
+
+    column1: [
+       {
+           xtype: 'proxmoxintegerfield',
+           name: 'sockets',
+           minValue: 1,
+           maxValue: 4,
+           value: '1',
+           fieldLabel: gettext('Sockets'),
+           allowBlank: false,
+           bind: {
+               value: '{socketCount}',
            },
-           {
-               xtype: 'displayfield',
-               fieldLabel: gettext('Total cores'),
-               name: 'totalcores',
-               value: '1'
-           }
+       },
+       {
+           xtype: 'proxmoxintegerfield',
+           name: 'cores',
+           minValue: 1,
+           maxValue: 256,
+           value: '1',
+           fieldLabel: gettext('Cores'),
+           allowBlank: false,
+           bind: {
+               value: '{coreCount}',
+           },
+       },
+    ],
 
-       ];
+    column2: [
+       {
+           xtype: 'CPUModelSelector',
+           name: 'cputype',
+           reference: 'cputype',
+           fieldLabel: gettext('Type'),
+       },
+       {
+           xtype: 'displayfield',
+           fieldLabel: gettext('Total cores'),
+           name: 'totalcores',
+           isFormField: false,
+           bind: {
+               value: '{totalCoreCount}',
+           },
+       },
+    ],
 
-       me.callParent();
-    }
+    columnB: [
+       {
+           xtype: 'displayfield',
+           userCls: 'pmx-hint',
+           value: gettext('WARNING: You do not have permission to configure custom CPU types, if you change the type you will not be able to go back!'),
+           hidden: true,
+           bind: {
+               hidden: '{!showCustomModelPermWarning}',
+           },
+       },
+    ],
+
+    advancedColumn1: [
+       {
+           xtype: 'proxmoxintegerfield',
+           name: 'vcpus',
+           minValue: 1,
+           maxValue: 1,
+           value: '',
+           fieldLabel: gettext('VCPUs'),
+           deleteEmpty: true,
+           allowBlank: true,
+           emptyText: '1',
+           bind: {
+               emptyText: '{totalCoreCount}',
+               maxValue: '{totalCoreCount}',
+           },
+       },
+       {
+           xtype: 'numberfield',
+           name: 'cpulimit',
+           minValue: 0,
+           maxValue: 128, // api maximum
+           value: '',
+           step: 1,
+           fieldLabel: gettext('CPU limit'),
+           allowBlank: true,
+           emptyText: gettext('unlimited'),
+       },
+       {
+           xtype: 'proxmoxtextfield',
+           name: 'affinity',
+           vtype: 'CpuSet',
+           value: '',
+           fieldLabel: gettext('CPU Affinity'),
+           allowBlank: true,
+           emptyText: gettext("All Cores"),
+           deleteEmpty: true,
+           bind: {
+               disabled: '{!userIsRoot}',
+           },
+       },
+    ],
+
+    advancedColumn2: [
+       {
+           xtype: 'proxmoxintegerfield',
+           name: 'cpuunits',
+           fieldLabel: gettext('CPU units'),
+           minValue: '1',
+           maxValue: '10000',
+           value: '',
+           emptyText: '100',
+           bind: {
+               minValue: '{cpuunitsMin}',
+               maxValue: '{cpuunitsMax}',
+               emptyText: '{cpuunitsDefault}',
+           },
+           deleteEmpty: true,
+           allowBlank: true,
+       },
+       {
+           xtype: 'proxmoxcheckbox',
+           fieldLabel: gettext('Enable NUMA'),
+           name: 'numa',
+           uncheckedValue: 0,
+       },
+    ],
+    advancedColumnB: [
+       {
+           xtype: 'label',
+           text: 'Extra CPU Flags:',
+       },
+       {
+           xtype: 'vmcpuflagselector',
+           name: 'flags',
+       },
+    ],
 });
 
 Ext.define('PVE.qemu.ProcessorEdit', {
-    extend: 'PVE.window.Edit',
+    extend: 'Proxmox.window.Edit',
+    alias: 'widget.pveQemuProcessorEdit',
 
-    initComponent : function() {
-       var me = this;
-       
-       var ipanel = Ext.create('PVE.qemu.ProcessorInputPanel')
+    width: 700,
+
+    viewModel: {
+       data: {
+           cgroupMode: 2,
+       },
+    },
+
+    initComponent: function() {
+       let me = this;
+       me.getViewModel().set('cgroupMode', me.cgroupMode);
+
+       var ipanel = Ext.create('PVE.qemu.ProcessorInputPanel');
 
        Ext.apply(me, {
            subject: gettext('Processors'),
-           items: ipanel
+           items: ipanel,
        });
 
        me.callParent();
@@ -125,9 +276,19 @@ Ext.define('PVE.qemu.ProcessorEdit', {
                    var cpu = PVE.Parser.parseQemuCpu(value);
                    ipanel.cpu = cpu;
                    data.cputype = cpu.cputype;
+                   if (cpu.flags) {
+                       data.flags = cpu.flags;
+                   }
+
+                   let caps = Ext.state.Manager.get('GuiCap');
+                   if (data.cputype.indexOf('custom-') === 0 &&
+                       !caps.nodes['Sys.Audit']) {
+                       let vm = ipanel.getViewModel();
+                       vm.set("showCustomModelPermWarning", true);
+                   }
                }
                me.setValues(data);
-           }
+           },
        });
-    }
+    },
 });