For this, introduce a new 'QemuMachineSelector', which does the same
thing as the scsihw selector by filtering the kv store with a predefined
list for each architecture.

Since the backend default of the machine is actually different for
x86_64 vs aarch64, there is some logic to handle the 'default' value
for the machine (iow. replace 'pc' with the default machine for each
architecture)

Signed-off-by: Dominik Csapak <[email protected]>
---
 www/manager6/Makefile                    |  1 +
 www/manager6/Utils.js                    | 18 ++++++-
 www/manager6/form/QemuMachineSelector.js | 64 ++++++++++++++++++++++++
 www/manager6/qemu/HardwareView.js        |  3 +-
 www/manager6/qemu/MachineEdit.js         | 63 +++++++++++++++++------
 www/manager6/qemu/SystemEdit.js          | 10 ++--
 6 files changed, 136 insertions(+), 23 deletions(-)
 create mode 100644 www/manager6/form/QemuMachineSelector.js

diff --git a/www/manager6/Makefile b/www/manager6/Makefile
index 4558d53e..7670b95d 100644
--- a/www/manager6/Makefile
+++ b/www/manager6/Makefile
@@ -62,6 +62,7 @@ JSSRC=                                                        
\
        form/PreallocationSelector.js                   \
        form/PrivilegesSelector.js                      \
        form/QemuBiosSelector.js                        \
+       form/QemuMachineSelector.js                     \
        form/SDNControllerSelector.js                   \
        form/SDNZoneSelector.js                         \
        form/SDNVnetSelector.js                         \
diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js
index de1ee0ba..613a7113 100644
--- a/www/manager6/Utils.js
+++ b/www/manager6/Utils.js
@@ -509,8 +509,22 @@ Ext.define('PVE.Utils', {
             return agentstring;
         },
 
-        render_qemu_machine: function (value) {
-            return value || Proxmox.Utils.defaultText + ' (i440fx)';
+        defaultMachines: {
+            x86_64: 'pc',
+            aarch64: 'virt',
+        },
+
+        machineText: {
+            pc: 'i440fx',
+        },
+
+        render_qemu_machine: function (value, arch = 'x86_64') {
+            if (!value) {
+                let machine = PVE.Utils.defaultMachines[arch];
+                let machineText = PVE.Utils.machineText[machine] ?? machine;
+                return `${Proxmox.Utils.defaultText} (${machineText})`;
+            }
+            return value;
         },
 
         render_qemu_bios: function (value) {
diff --git a/www/manager6/form/QemuMachineSelector.js 
b/www/manager6/form/QemuMachineSelector.js
new file mode 100644
index 00000000..2852b585
--- /dev/null
+++ b/www/manager6/form/QemuMachineSelector.js
@@ -0,0 +1,64 @@
+Ext.define('PVE.form.QemuMachineSelector', {
+    extend: 'Proxmox.form.KVComboBox',
+    alias: 'widget.pveQemuMachineSelector',
+
+    comboItems: [
+        ['__default__', PVE.Utils.render_qemu_machine('')],
+        ['q35', 'q35'],
+    ],
+
+    machinesPerArchitecture: {
+        x86_64: ['__default__', 'q35'], // __default__ is i440fx
+        aarch64: ['__default__'], // __default__ is virt
+    },
+
+    // defaults to hostArch
+    arch: undefined,
+
+    // depends on the node
+    hostArch: 'x86_64',
+
+    nodename: undefined,
+
+    setNodename: function (nodename) {
+        let me = this;
+        let node = PVE.data.ResourceStore.getNodeById(nodename);
+        if (node) {
+            me.hostArch = node.data.architecture;
+            me.setArch(me.arch); // recalculate the filter
+        }
+    },
+
+    setArch: function (arch) {
+        let me = this;
+        if (arch === '__default__') {
+            arch = undefined;
+        }
+        me.arch = arch;
+        arch ??= me.hostArch;
+        let wasValid = me.isValid();
+        me.store.clearFilter();
+        let allowedMachines = me.machinesPerArchitecture[arch];
+        me.store.addFilter((rec) => allowedMachines.indexOf(rec.data.key) !== 
-1);
+        // update default value with new arch
+        let record = me.store.findRecord('key', '__default__');
+        if (record) {
+            record.set('value', PVE.Utils.render_qemu_machine('', arch));
+            record.commit();
+        }
+        let isValid = me.isValid();
+
+        // for some reason, adding/changing filters does not trigger this, 
even though
+        // it show the field as invalid, so simply track and fire the event 
manually.
+        if (wasValid !== isValid) {
+            me.fireEvent('validitychange', isValid);
+        }
+    },
+
+    initComponent: function () {
+        var me = this;
+
+        me.callParent();
+        me.setArch(me.arch);
+    },
+});
diff --git a/www/manager6/qemu/HardwareView.js 
b/www/manager6/qemu/HardwareView.js
index b7cc7856..1e2cd026 100644
--- a/www/manager6/qemu/HardwareView.js
+++ b/www/manager6/qemu/HardwareView.js
@@ -202,13 +202,14 @@ Ext.define('PVE.qemu.HardwareView', {
                 defaultValue: '',
                 renderer: function (value, metaData, record, rowIndex, 
colIndex, store, pending) {
                     let ostype = me.getObjectValue('ostype', undefined, 
pending);
+                    let arch = 
PVE.Utils.getArchitecture(me.getObjectValue('arch'), nodename);
                     if (
                         PVE.Utils.is_windows(ostype) &&
                         (!value || value === 'pc' || value === 'q35')
                     ) {
                         return value === 'q35' ? 'pc-q35-5.1' : 
'pc-i440fx-5.1';
                     }
-                    return PVE.Utils.render_qemu_machine(value);
+                    return PVE.Utils.render_qemu_machine(value, arch);
                 },
             },
             scsihw: {
diff --git a/www/manager6/qemu/MachineEdit.js b/www/manager6/qemu/MachineEdit.js
index 1b1989e8..89d13886 100644
--- a/www/manager6/qemu/MachineEdit.js
+++ b/www/manager6/qemu/MachineEdit.js
@@ -23,8 +23,16 @@ Ext.define('PVE.qemu.MachineInputPanel', {
             let me = this;
             let version = me.lookup('version');
             let store = version.getStore();
+
             let oldRec = store.findRecord('id', version.getValue(), 0, false, 
false, true);
-            let type = value === 'q35' ? 'q35' : 'i440fx';
+
+            let vm = me.getViewModel();
+            let arch = PVE.Utils.getArchitecture(vm.get('arch'), 
vm.get('nodename'));
+            let defaultMachine = PVE.Utils.defaultMachines[arch];
+            if (defaultMachine === 'pc') {
+                defaultMachine = 'i440fx'; // the default in the backend is 
'pc' which means 'i440fx' for the qemu machinetype'
+            }
+            let type = value === 'q35' ? 'q35' : defaultMachine;
             store.clearFilter();
             store.addFilter((val) => val.data.id === 'latest' || val.data.type 
=== type);
             if (!me.getView().isWindows) {
@@ -45,9 +53,12 @@ Ext.define('PVE.qemu.MachineInputPanel', {
     },
 
     onGetValues: function (values) {
+        let me = this;
+        let arch = PVE.Utils.getArchitecture(values.arch, me.nodename);
+        delete values.arch;
         if (values.delete === 'machine' && values.viommu) {
             delete values.delete;
-            values.machine = 'pc';
+            values.machine = PVE.Utils.defaultMachines[arch];
         }
         if (values.version && values.version !== 'latest') {
             values.machine = values.version;
@@ -68,8 +79,10 @@ Ext.define('PVE.qemu.MachineInputPanel', {
         let machineConf = PVE.Parser.parsePropertyString(values.machine, 
'type');
         values.machine = machineConf.type;
 
+        let arch = PVE.Utils.getArchitecture(values.arch, me.nodename);
+        let defaultMachine = PVE.Utils.defaultMachines[arch];
         me.isWindows = values.isWindows;
-        if (values.machine === 'pc') {
+        if (values.machine === defaultMachine) {
             values.machine = '__default__';
         }
 
@@ -94,19 +107,31 @@ Ext.define('PVE.qemu.MachineInputPanel', {
         this.callParent(arguments);
     },
 
-    items: {
-        xtype: 'proxmoxKVComboBox',
-        name: 'machine',
-        reference: 'machine',
-        fieldLabel: gettext('Machine'),
-        comboItems: [
-            ['__default__', PVE.Utils.render_qemu_machine('')],
-            ['q35', 'q35'],
-        ],
-        bind: {
-            value: '{type}',
+    items: [
+        {
+            xtype: 'pveQemuMachineSelector',
+            name: 'machine',
+            reference: 'machine',
+            fieldLabel: gettext('Machine'),
+            bind: {
+                value: '{type}',
+                arch: '{arch}',
+                nodename: '{nodename}',
+            },
         },
-    },
+        {
+            xtype: 'hidden',
+            name: 'arch',
+            reference: 'arch',
+            bind: '{arch}',
+        },
+        {
+            xtype: 'hidden',
+            name: 'nodename',
+            submitValue: false,
+            bind: '{nodename}',
+        },
+    ],
 
     advancedItems: [
         {
@@ -197,6 +222,12 @@ Ext.define('PVE.qemu.MachineEdit', {
     initComponent: function () {
         let me = this;
 
+        me.nodename = me.pveSelNode?.data.node;
+
+        if (!me.nodename) {
+            throw 'no nodename given';
+        }
+
         me.callParent();
 
         me.load({
@@ -206,6 +237,8 @@ Ext.define('PVE.qemu.MachineEdit', {
                     machine: conf.machine || '__default__',
                 };
                 values.isWindows = PVE.Utils.is_windows(conf.ostype);
+                values.arch = PVE.Utils.getArchitecture(conf.arch, 
me.nodename);
+                values.nodename = me.nodename;
                 me.setValues(values);
             },
         });
diff --git a/www/manager6/qemu/SystemEdit.js b/www/manager6/qemu/SystemEdit.js
index a2ad8494..71fd1125 100644
--- a/www/manager6/qemu/SystemEdit.js
+++ b/www/manager6/qemu/SystemEdit.js
@@ -83,15 +83,15 @@ Ext.define('PVE.qemu.SystemInputPanel', {
             comboItems: Object.entries(PVE.Utils.kvm_vga_drivers),
         },
         {
-            xtype: 'proxmoxKVComboBox',
+            xtype: 'pveQemuMachineSelector',
             name: 'machine',
             reference: 'machine',
             value: '__default__',
             fieldLabel: gettext('Machine'),
-            comboItems: [
-                ['__default__', PVE.Utils.render_qemu_machine('')],
-                ['q35', 'q35'],
-            ],
+            bind: {
+                arch: '{current.architecture}',
+                nodename: '{nodename}',
+            },
         },
         {
             xtype: 'displayfield',
-- 
2.47.3



_______________________________________________
pve-devel mailing list
[email protected]
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to