From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 118691FF143 for ; Sat, 25 Apr 2026 14:39:55 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 90EB3364; Sat, 25 Apr 2026 14:39:52 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 smtp.gnome.org CE9F51099C1E2 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gnome.org; s=default; t=1777120353; bh=ow0ytmH+z/5P2ug3mjKeZSNoDil3p8LQNb1oNglnPCw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=zPAfANI7NmCIkZXxkeE0gg/iUTNIH7mMYFcqYooiqNn60dHjJ+Z4MczSgKC6IlVyV qWOs6mDV+5y/pK5HCdgtFE9h0486OKw1xFz+uKZOzS9rAuarbzshFRruAPPgJw3taE +AdGqiMDktUWsueZXbfBWftM2VDZo/OoFJbdjCFM= From: Yuri Konotopov To: pve-devel@lists.proxmox.com Subject: [PATCH pve-manager] fix #1739: ui: qemu: expose cloud-init instance-id mode Date: Sat, 25 Apr 2026 16:31:25 +0400 Message-ID: <20260425123125.797431-4-ykonotopov@gnome.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260425123125.797431-1-ykonotopov@gnome.org> References: <20260425123125.797431-1-ykonotopov@gnome.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 BAYES_00 -1.9 Bayes spam probability is 0 to 1% DKIM_SIGNED 0.1 Message has a DKIM or DK signature, not necessarily valid DKIM_VALID -0.1 Message has at least one valid DKIM or DK signature DKIM_VALID_AU -0.1 Message has a valid DKIM or DK signature from author's domain DKIM_VALID_EF -0.1 Message has a valid DKIM or DK signature from envelope-from domain DMARC_PASS -0.1 DMARC pass policy RCVD_IN_DNSWL_LOW -0.7 Sender listed at https://www.dnswl.org/, low trust SPF_HELO_PASS -0.001 SPF: HELO matches SPF record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: YQWM26K2D4MBX5MXTGYENAWZHY5TNQLP X-Message-ID-Hash: YQWM26K2D4MBX5MXTGYENAWZHY5TNQLP X-MailFrom: ykonotopov@gnome.org 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: Yuri Konotopov X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Yuri Konotopov --- www/manager6/Makefile | 1 + www/manager6/qemu/CIInstanceIdEdit.js | 120 ++++++++++++++++++++++++++ www/manager6/qemu/CloudInit.js | 17 ++++ 3 files changed, 138 insertions(+) create mode 100644 www/manager6/qemu/CIInstanceIdEdit.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index b506849d..510c5502 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -248,6 +248,7 @@ JSSRC= \ qemu/BootOrderEdit.js \ qemu/CDEdit.js \ qemu/CIDriveEdit.js \ + qemu/CIInstanceIdEdit.js \ qemu/CloudInit.js \ qemu/CmdMenu.js \ qemu/Config.js \ diff --git a/www/manager6/qemu/CIInstanceIdEdit.js b/www/manager6/qemu/CIInstanceIdEdit.js new file mode 100644 index 00000000..71d42f93 --- /dev/null +++ b/www/manager6/qemu/CIInstanceIdEdit.js @@ -0,0 +1,120 @@ +Ext.define('PVE.qemu.CIInstanceIdInputPanel', { + extend: 'Proxmox.panel.InputPanel', + alias: 'widget.pveCIInstanceIdInputPanel', + + effectiveInstanceId: undefined, + + onGetValues: function (values) { + let data = { + mode: values.mode, + id: values.mode === 'persistent' ? values.id : undefined, + }; + + if (!data.id) { + delete data.id; + } + + return { + ciinstanceid: PVE.Parser.printPropertyString(data), + }; + }, + + setCiInstanceId: function (value, effectiveInstanceId) { + let data = value ? PVE.Parser.parsePropertyString(value) : {}; + data.mode = data.mode || 'legacy'; + data.id = data.id || effectiveInstanceId || ''; + + this.effectiveInstanceId = effectiveInstanceId; + this.setValues(data); + this.down('field[name=id]').setDisabled(data.mode === 'legacy'); + }, + + items: [ + { + xtype: 'proxmoxKVComboBox', + name: 'mode', + fieldLabel: gettext('Mode'), + comboItems: [ + ['legacy', gettext('Legacy')], + ['persistent', gettext('Persistent')], + ], + value: 'legacy', + allowBlank: false, + listeners: { + change: function (field, value) { + let ipanel = field.up('inputpanel'); + let idField = ipanel.down('field[name=id]'); + idField.setDisabled(value === 'legacy'); + if (value === 'persistent' && !idField.getValue()) { + idField.setValue(ipanel.effectiveInstanceId || ''); + } + }, + }, + }, + { + xtype: 'proxmoxtextfield', + name: 'id', + fieldLabel: gettext('Instance ID'), + allowBlank: true, + disabled: true, + validator: function (value) { + if (!value) { + return true; + } + return /^[A-Za-z0-9][A-Za-z0-9_.:-]{0,63}$/.test(value) + ? true + : gettext('Invalid Instance ID'); + }, + }, + ], +}); + +Ext.define('PVE.qemu.CIInstanceIdEdit', { + extend: 'Proxmox.window.Edit', + + initComponent: function () { + let me = this; + + let ipanel = Ext.create('PVE.qemu.CIInstanceIdInputPanel'); + let configValue; + let effectiveInstanceId; + let loadedConfig = false; + let loadedInstanceId = false; + + let applyValues = function () { + if (loadedConfig && loadedInstanceId) { + ipanel.setCiInstanceId(configValue, effectiveInstanceId); + } + }; + + Ext.apply(me, { + subject: gettext('Instance ID'), + width: 450, + items: [ipanel], + }); + + me.callParent(); + + me.load({ + success: function (response) { + configValue = response.result.data.ciinstanceid; + loadedConfig = true; + applyValues(); + }, + }); + + Proxmox.Utils.API2Request({ + url: me.baseurl + '/cloudinit/instance-id', + method: 'GET', + success: function (response) { + effectiveInstanceId = response.result.data.id; + loadedInstanceId = true; + applyValues(); + }, + failure: function () { + loadedInstanceId = true; + applyValues(); + }, + }); + }, +}); diff --git a/www/manager6/qemu/CloudInit.js b/www/manager6/qemu/CloudInit.js index b0304442..c8d2413e 100644 --- a/www/manager6/qemu/CloudInit.js +++ b/www/manager6/qemu/CloudInit.js @@ -166,6 +166,7 @@ Ext.define('PVE.qemu.CloudInit', { me.baseurl = '/api2/extjs/nodes/' + nodename + '/qemu/' + vmid; me.url = me.baseurl + '/pending'; me.editorConfig.url = me.baseurl + '/config'; + me.editorConfig.baseurl = me.baseurl; me.editorConfig.pveSelNode = me.pveSelNode; let caps_ci = caps.vms['VM.Config.Cloudinit'] || caps.vms['VM.Config.Network']; @@ -287,6 +288,22 @@ Ext.define('PVE.qemu.CloudInit', { }, }, }, + ciinstanceid: { + header: gettext('Instance ID'), + iconCls: 'fa fa-id-card-o', + renderer: function (value) { + let data = value ? PVE.Parser.parsePropertyString(value) : {}; + let mode = data.mode || 'legacy'; + let modes = { + legacy: gettext('Legacy'), + persistent: gettext('Persistent'), + }; + + return modes[mode]; + }, + defaultValue: 'mode=legacy', + editor: caps_ci ? 'PVE.qemu.CIInstanceIdEdit' : undefined, + }, }; var i; var ipconfig_renderer = function (value, md, record, ri, ci, store, pending) { -- 2.47.3