From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gate001.proxmox.com (gate001.proxmox.com [45.144.208.40]) by lore.proxmox.com (Postfix) with ESMTPS id 3CAE61FF0B3 for ; Wed, 19 Aug 2026 11:29:10 +0200 (CEST) Received: from gate001.proxmox.com (localhost.localdomain [127.0.0.1]) by gate001.proxmox.com (Proxmox) with ESMTP id B4C48214EB; Wed, 19 Aug 2026 11:29:06 +0200 (CEST) From: Jakob Klocker To: pve-devel@lists.proxmox.com Subject: [PATCH manager] fix #7896: ui: qemu: show effective machine version for Windows guests Date: Wed, 19 Aug 2026 11:28:33 +0200 Message-ID: <20260819092833.114930-1-j.klocker@proxmox.com> X-Mailer: git-send-email 2.47.3 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 1 AWL -0.600 Adjusted score from AWL reputation of From: address DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment (newer systems) KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods PROLO_LEO1 0.1 Meta Catches all Leo drug variations so far RDNS_NONE 1.274 Delivered to internal network by a host with no rDNS SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record Message-ID-Hash: EKDMHGU4SBRAMFD6ZDSA33LUO76GLIOW X-Message-ID-Hash: EKDMHGU4SBRAMFD6ZDSA33LUO76GLIOW X-MailFrom: jklocker@iris.proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Jakob Klocker X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Windows guests without an explicitly pinned machine version still run with a fixed one: guests created with QEMU 9.1 or newer keep the version they were created with, older ones fall back to 5.1. The GUI assumed the 5.1 fallback unconditionally, so guests created with a newer QEMU were shown a version they are not running. Derive the version from the QEMU version recorded at creation time instead, in both the hardware view and the machine edit dialog, and mark it as implicit so it stays distinguishable from an explicit pin. The edit dialog also pre-filled the version field with the fallback, which both suggested a version the guest might not be running and caused any other change in the dialog to submit that stale value. Leave the selector at 'latest' instead, so a version can be picked deliberately, and show the effective version as a read-only field together with a hint recommending an explicit pin. The advanced section is expanded so the hint is visible without further interaction. Link: https://bugzilla.proxmox.com/show_bug.cgi?id=7896 Signed-off-by: Jakob Klocker --- www/manager6/Utils.js | 21 +++++++++++++++++ www/manager6/qemu/HardwareView.js | 19 +++++++++++++++- www/manager6/qemu/MachineEdit.js | 38 +++++++++++++++++++++++++++---- 3 files changed, 73 insertions(+), 5 deletions(-) diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index c86a00c5..4d6606af 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -1822,6 +1822,27 @@ Ext.define('PVE.Utils', { return true; }, + qemu_implicit_machine_version: function (machineType, creationQemu, arch) { + let baseVersion = '5.1'; + let m = creationQemu?.match(/^(\d+)\.(\d+)/); + if (m) { + let major = parseInt(m[1], 10); + let minor = parseInt(m[2], 10); + if (major > 9 || (major === 9 && minor >= 1)) { + baseVersion = `${major}.${minor}`; + } + } + + let base; + if (machineType === 'q35') { + base = 'pc-q35'; + } else { + let defaultMachine = PVE.qemu.Architecture.defaultMachines[arch]; + base = defaultMachine === 'virt' ? 'virt' : 'pc-i440fx'; + } + return `${base}-${baseVersion}`; + }, + cleanEmptyObjectKeys: function (obj) { for (const propName of Object.keys(obj)) { if (obj[propName] === null || obj[propName] === undefined) { diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js index e6c02299..eeb86397 100644 --- a/www/manager6/qemu/HardwareView.js +++ b/www/manager6/qemu/HardwareView.js @@ -201,7 +201,21 @@ Ext.define('PVE.qemu.HardwareView', { PVE.Utils.is_windows(ostype) && (!value || value === 'pc' || value === 'q35') ) { - return value === 'q35' ? 'pc-q35-5.1' : 'pc-i440fx-5.1'; + let meta = me.getObjectValue('meta', undefined, pending); + let creationQemu; + if (meta) { + creationQemu = PVE.Parser.parsePropertyString(meta)['creation-qemu']; + } + let machineType = value === 'q35' ? 'q35' : '__default__'; + return ( + PVE.Utils.qemu_implicit_machine_version( + machineType, + creationQemu, + arch, + ) + + ' ' + + gettext('(implicit)') + ); } return PVE.Utils.render_qemu_machine(value, arch); }, @@ -254,6 +268,9 @@ Ext.define('PVE.qemu.HardwareView', { ostype: { visible: false, }, + meta: { + visible: false, + }, affinity: { visible: false, }, diff --git a/www/manager6/qemu/MachineEdit.js b/www/manager6/qemu/MachineEdit.js index 4b1a9e83..6fda7715 100644 --- a/www/manager6/qemu/MachineEdit.js +++ b/www/manager6/qemu/MachineEdit.js @@ -6,6 +6,7 @@ Ext.define('PVE.qemu.MachineInputPanel', { viewModel: { data: { type: '__default__', + effectiveVersionLabel: '', }, formulas: { q35: (get) => get('type') === 'q35', @@ -102,10 +103,17 @@ Ext.define('PVE.qemu.MachineInputPanel', { } if (me.isWindows) { - if (values.machine === '__default__') { - values.version = 'pc-i440fx-5.1'; - } else if (values.machine === 'q35') { - values.version = 'pc-q35-5.1'; + if (values.machine === '__default__' || values.machine === 'q35') { + let effective = PVE.Utils.qemu_implicit_machine_version( + values.machine, + values.creationQemu, + values.arch, + ); + me.getViewModel().set( + 'effectiveVersionLabel', + effective + ' ' + gettext('(implicit)'), + ); + me.setAdvancedVisible(true); } } @@ -176,6 +184,23 @@ Ext.define('PVE.qemu.MachineInputPanel', { }, }, }, + { + xtype: 'displayfield', + fieldLabel: gettext('Current Version'), + bind: { + value: '{effectiveVersionLabel}', + hidden: '{!effectiveVersionLabel}', + }, + }, + { + xtype: 'displayfield', + userCls: 'pmx-hint', + value: gettext( + 'No fixed version is set; the version is chosen automatically based on when the VM' + + ' was created. Pinning a specific version is recommended.', + ), + bind: { hidden: '{!effectiveVersionLabel}' }, + }, { xtype: 'displayfield', fieldLabel: gettext('Note'), @@ -249,6 +274,11 @@ Ext.define('PVE.qemu.MachineEdit', { }; values.isWindows = PVE.Utils.is_windows(conf.ostype); values.arch = PVE.qemu.Architecture.getGuestArchitecture(conf.arch, me.nodename); + if (conf.meta) { + let meta = PVE.Parser.parsePropertyString(conf.meta); + values.creationQemu = meta['creation-qemu']; + } + me.setValues(values); }, }); -- 2.47.3