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
