diff --git a/www/manager6/qemu/OSDefaults.js b/www/manager6/qemu/OSDefaults.js new file mode 100644 index 0000000..df5ad8a --- /dev/null +++ b/www/manager6/qemu/OSDefaults.js @@ -0,0 +1,133 @@ +/* + * This class holds performance *recommended* settings for the PVE Qemu wizards + * the *mandatory* settings are set in the PVE::QemuServer + * config_to_command sub + * We store this here until we get the data from the API server + */ + +// this is how you would add an hypothetic FreeBSD > 10 entry +// +//virtio-blk is stable but virtIO net still +// problematic as of 10.3 +// see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=165059 +// addOS({ +// parent: 'generic', // inherits defaults +// pveOS: 'freebsd10', // must match a radiofield in OSTypeEdit.js +// busType: 'virtio' // must match a pveBusController value +// // networkCard muss match a pveNetworkCardSelector + +Ext.define('PVE.qemu.OSDefaults', { + singleton: true, // will also force creation when loaded + + constructor: function () { + let me = this; + + let addOS = function (settings) { + if (Object.hasOwn(settings, 'parent')) { + let architectures = settings.architectures; + delete settings.architectures; + + let child = { + x86_64: Ext.apply({}, settings, me[settings.parent].x86_64), + }; + + for (const arch of Object.keys(architectures ?? {})) { + child[arch] = Ext.apply({}, architectures[arch], me[settings.parent][arch]); + } + me[settings.pveOS] = child; + } else { + throw 'Could not find your genitor'; + } + }; + + // default values + me.generic = { + x86_64: { + busType: 'ide', + networkCard: 'e1000', + busPriority: { + ide: 4, + sata: 3, + scsi: 2, + virtio: 1, + }, + scsihw: 'virtio-scsi-single', + }, + + aarch64: { + // aarch64 has no ide, and ovmf can't boot from sata + busType: 'scsi', + networkCard: 'e1000', + busPriority: { + scsi: 4, + sata: 3, + virtio: 2, + ide: 1, + }, + scsihw: 'virtio-scsi-single', + bios: 'ovmf', + }, + }; + + // virtio-net is in kernel since 2.6.25 + // virtio-scsi since 3.2 but backported in RHEL with 2.6 kernel + addOS({ + pveOS: 'l26', + parent: 'generic', + busType: 'scsi', + busPriority: { + scsi: 4, + virtio: 3, + sata: 2, + ide: 1, + }, + networkCard: 'virtio', + + architectures: { + aarch64: { + busPriority: { + scsi: 4, + virtio: 2, + sata: 2, + ide: 1, + }, + networkCard: 'virtio', + }, + }, + }); + + // recommendation from http://wiki.qemu.org/Windows2000 + addOS({ + pveOS: 'w2k', + parent: 'generic', + networkCard: 'rtl8139', + scsihw: '', + }); + // https://pve.proxmox.com/wiki/Windows_XP_Guest_Notes + addOS({ + pveOS: 'wxp', + parent: 'w2k', + }); + + addOS({ + pveOS: 'win11', + parent: 'generic', + machine: 'q35', + bios: 'ovmf', + }); + + me.getDefaults = function (ostype, arch = 'x86_64') { + if (!PVE.qemu.OSDefaults[ostype]) { + ostype = 'generic'; + } + + let os = PVE.qemu.OSDefaults[ostype]; + if (os[arch]) { + return os[arch]; + } + + // default + return os.x86_64; + }; + }, +}); diff --git a/www/manager6/qemu/OSPanel.js b/www/manager6/qemu/OSPanel.js new file mode 100644 index 0000000..556ad4c --- /dev/null +++ b/www/manager6/qemu/OSPanel.js @@ -0,0 +1,175 @@ +/// Used only for the wizard to combine the cd input panel and the ostype panel + +Ext.define('PVE.qemu.OSPanel', { + extend: 'Ext.panel.Panel', + xtype: 'pveQemuOSPanel', + + layout: 'hbox', + defaults: { + flex: 1, + padding: '0 10', + }, + + setArch: function (arch) { + let me = this; + let defaultCD = PVE.qemu.Architecture.defaultCDDrive; + let [controller, id] = defaultCD[arch] ?? defaultCD.x86_64; + let vm = me.getController().getViewModel(); + let conf = `${controller}${id}`; + vm.set('current.isoConfig', conf); + me.lookup('cdSelector').confid = conf; + // TODO change confid for second cd if windows is allowed for other architectures + }, + + controller: { + xclass: 'Ext.app.ViewController', + control: { + 'combobox[name=osbase]': { + change: 'onOSBaseChange', + }, + 'combobox[name=ostype]': { + afterrender: 'onOSTypeChange', + change: 'onOSTypeChange', + }, + 'checkbox[reference=enableSecondCD]': { + change: 'onSecondCDChange', + }, + }, + onOSBaseChange: function (field, value) { + let me = this; + let isWindows = value === 'Microsoft Windows'; + let enableSecondCD = me.lookup('enableSecondCD'); + enableSecondCD.setVisible(isWindows); + if (!isWindows) { + enableSecondCD.setValue(false); + } + }, + onOSTypeChange: function (field) { + var me = this, + ostype = field.getValue(); + + let arch = me.getViewModel().get('current.architecture'); + var targetValues = PVE.qemu.OSDefaults.getDefaults(ostype, arch); + + me.setWidget('pveBusSelector', targetValues.busType); + me.setWidget('pveNetworkCardSelector', targetValues.networkCard); + me.setWidget('CPUModelSelector', targetValues.cputype); + var scsihw = targetValues.scsihw || '__default__'; + this.getViewModel().set('current.scsihw', scsihw); + this.getViewModel().set('current.ostype', ostype); + }, + setWidget: function (widget, newValue) { + // changing a widget is safe only if ComponentQuery.query returns us + // a single value array + var widgets = Ext.ComponentQuery.query('pveQemuCreateWizard ' + widget); + if (widgets.length === 1) { + widgets[0].setValue(newValue); + } else { + // ignore multiple disks, we only want to set the type if there is a single disk + } + }, + onSecondCDChange: function (widget, value, lastValue) { + let me = this; + let vm = me.getViewModel(); + let updateVMConfig = function () { + let widgets = Ext.ComponentQuery.query('pveMultiHDPanel'); + if (widgets.length === 1) { + widgets[0].getController().updateVMConfig(); + } + }; + if (value) { + // only for windows + vm.set('current.ide0', 'some'); + vm.notify(); + updateVMConfig(); + me.setWidget('pveBusSelector', 'scsi'); + me.setWidget('pveNetworkCardSelector', 'virtio'); + } else { + vm.set('current.ide0', ''); + vm.notify(); + updateVMConfig(); + me.setWidget('pveBusSelector', 'scsi'); + let ostype = me.getView().down('[name=ostype]').getValue(); + let arch = vm.get('current.architecture'); + let targetValues = PVE.qemu.OSDefaults.getDefaults(ostype, arch); + me.setWidget('pveBusSelector', targetValues.busType); + } + }, + }, + + items: [ + { + xtype: 'pveQemuCDInputPanel', + reference: 'cdSelector', + bind: { + nodename: '{nodename}', + }, + confid: 'ide2', + insideWizard: true, + }, + { + xtype: 'container', + layout: { + type: 'vbox', + align: 'stretch', + }, + defaults: { + flex: 1, + }, + items: [ + { + xtype: 'displayfield', + value: gettext('Guest OS') + ':', + }, + { + xtype: 'pveQemuOSTypePanel', + insideWizard: true, + bind: { + arch: '{current.architecture}', + }, + }, + { + xtype: 'inputpanel', + onGetValues: function (values) { + if (values.ide0) { + let drive = { + media: 'cdrom', + file: values.ide0, + }; + values.ide0 = PVE.Parser.printQemuDrive(drive); + } + return values; + }, + items: [ + { + xtype: 'proxmoxcheckbox', + reference: 'enableSecondCD', + isFormField: false, + hidden: true, + checked: false, + boxLabel: gettext('Add additional drive for VirtIO drivers'), + listeners: { + change: function (cb, value) { + let me = this.up('pveQemuOSPanel'); + me.lookup('isoSelector').setDisabled(!value); + me.lookup('isoSelector').setHidden(!value); + }, + }, + }, + { + xtype: 'pveIsoSelector', + reference: 'isoSelector', + name: 'ide0', + insideWizard: true, + hidden: true, + disabled: true, + bind: { + nodename: '{nodename}', + }, + }, + ], + }, + ], + }, + ], +});