]> git.proxmox.com Git - pve-manager.git/blobdiff - www/manager6/qemu/ProcessorEdit.js
api: add proxmox-firewall to versions pkg list
[pve-manager.git] / www / manager6 / qemu / ProcessorEdit.js
index 4c0524eb1ac74664a1623d8629e1f67f5cd9c618..b35387274e00843eb7a15b102b31a34d8116995c 100644 (file)
@@ -1,3 +1,4 @@
+// The view model of the parent shoul contain a 'cgroupMode' variable (or params for v2 are used).
 Ext.define('PVE.qemu.ProcessorInputPanel', {
     extend: 'Proxmox.panel.InputPanel',
     alias: 'widget.pveQemuProcessorPanel',
@@ -5,61 +6,58 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
 
     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();
 
-       updateCores: function() {
-           var me = this.getView();
-           var sockets = me.down('field[name=sockets]').getValue();
-           var cores = me.down('field[name=cores]').getValue();
-           me.down('field[name=totalcores]').setValue(sockets*cores);
-           var vcpus = me.down('field[name=vcpus]');
-           vcpus.setMaxValue(sockets*cores);
-           vcpus.setEmptyText(sockets*cores);
-           vcpus.validate();
+           viewModel.set('userIsRoot', Proxmox.UserName === 'root@pam');
        },
-
-       control: {
-           'field[name=sockets]': {
-               change: 'updateCores'
-           },
-           'field[name=cores]': {
-               change: 'updateCores'
-           }
-       }
     },
 
     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(',');
+       if (Array.isArray(values.delete)) {
+           values.delete = values.delete.join(',');
        }
 
-       PVE.Utils.delete_if_default(values, 'cpulimit', '0', 0);
-       PVE.Utils.delete_if_default(values, 'cpuunits', '1024', 0);
+       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;
 
-       var flags = [];
-
-       ['pcid', 'spec-ctrl'].forEach(function(flag) {
-           if (values[flag]) {
-               flags.push('+' + flag.toString());
-           }
-           delete values[flag];
-       });
-
-       me.cpu.flags = flags.length ? flags.join(';') : undefined;
+       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');
@@ -75,12 +73,39 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
 
        var delarr = del.join(',');
        if (delarr) {
-           values['delete'] = delarr;
+           values.delete = delarr;
        }
 
        return values;
     },
 
+    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]);
+    },
+
     cpu: {},
 
     column1: [
@@ -91,32 +116,53 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
            maxValue: 4,
            value: '1',
            fieldLabel: gettext('Sockets'),
-           allowBlank: false
+           allowBlank: false,
+           bind: {
+               value: '{socketCount}',
+           },
        },
        {
            xtype: 'proxmoxintegerfield',
            name: 'cores',
            minValue: 1,
-           maxValue: 128,
+           maxValue: 256,
            value: '1',
            fieldLabel: gettext('Cores'),
-           allowBlank: false
-       }
+           allowBlank: false,
+           bind: {
+               value: '{coreCount}',
+           },
+       },
     ],
 
     column2: [
        {
            xtype: 'CPUModelSelector',
            name: 'cputype',
-           value: '__default__',
-           fieldLabel: gettext('Type')
+           reference: 'cputype',
+           fieldLabel: gettext('Type'),
        },
        {
            xtype: 'displayfield',
            fieldLabel: gettext('Total cores'),
            name: 'totalcores',
-           value: '1'
-       }
+           isFormField: false,
+           bind: {
+               value: '{totalCoreCount}',
+           },
+       },
+    ],
+
+    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: [
@@ -129,7 +175,11 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
            fieldLabel: gettext('VCPUs'),
            deleteEmpty: true,
            allowBlank: true,
-           emptyText: '1'
+           emptyText: '1',
+           bind: {
+               emptyText: '{totalCoreCount}',
+               maxValue: '{totalCoreCount}',
+           },
        },
        {
            xtype: 'numberfield',
@@ -140,53 +190,80 @@ Ext.define('PVE.qemu.ProcessorInputPanel', {
            step: 1,
            fieldLabel: gettext('CPU limit'),
            allowBlank: true,
-           emptyText: gettext('unlimited')
+           emptyText: gettext('unlimited'),
        },
        {
-           xtype: 'proxmoxintegerfield',
-           name: 'cpuunits',
-           fieldLabel: gettext('CPU units'),
-           minValue: 8,
-           maxValue: 500000,
-           value: '1024',
+           xtype: 'proxmoxtextfield',
+           name: 'affinity',
+           vtype: 'CpuSet',
+           value: '',
+           fieldLabel: gettext('CPU Affinity'),
+           allowBlank: true,
+           emptyText: gettext("All Cores"),
            deleteEmpty: true,
-           allowBlank: 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
+           uncheckedValue: 0,
        },
+    ],
+    advancedColumnB: [
        {
-           xtype: 'proxmoxcheckbox',
-           fieldLabel: 'PCID',
-           name: 'pcid',
-           uncheckedValue: 0
+           xtype: 'label',
+           text: 'Extra CPU Flags:',
        },
        {
-           xtype: 'proxmoxcheckbox',
-           fieldLabel: 'SPEC-CTRL',
-           name: 'spec-ctrl',
-           uncheckedValue: 0
-       }
-    ]
+           xtype: 'vmcpuflagselector',
+           name: 'flags',
+       },
+    ],
 });
 
 Ext.define('PVE.qemu.ProcessorEdit', {
     extend: 'Proxmox.window.Edit',
+    alias: 'widget.pveQemuProcessorEdit',
+
+    width: 700,
 
-    initComponent : function() {
-       var me = this;
+    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();
@@ -200,16 +277,18 @@ Ext.define('PVE.qemu.ProcessorEdit', {
                    ipanel.cpu = cpu;
                    data.cputype = cpu.cputype;
                    if (cpu.flags) {
-                       var flags = cpu.flags.split(';');
-                       flags.forEach(function(flag) {
-                           var sign = flag.substr(0,1);
-                           flag = flag.substr(1);
-                           data[flag] = (sign === '+');
-                       });
+                       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);
-           }
+           },
        });
-    }
+    },
 });