From: Yuri Konotopov <ykonotopov@gnome.org>
To: pve-devel@lists.proxmox.com
Cc: Yuri Konotopov <ykonotopov@gnome.org>
Subject: [PATCH pve-manager] fix #1739: ui: qemu: expose cloud-init instance-id mode
Date: Sat, 25 Apr 2026 16:31:25 +0400 [thread overview]
Message-ID: <20260425123125.797431-4-ykonotopov@gnome.org> (raw)
In-Reply-To: <20260425123125.797431-1-ykonotopov@gnome.org>
Signed-off-by: Yuri Konotopov <ykonotopov@gnome.org>
---
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
prev parent reply other threads:[~2026-04-25 12:39 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-25 12:31 [PATCH qemu-server/pve-manager 0/3] add ci " Yuri Konotopov
2026-04-25 12:31 ` [PATCH qemu-server 1/2] cloud-init: factor out generated file preparation Yuri Konotopov
2026-04-25 12:31 ` [PATCH qemu-server 2/2] fix #1739: cloud-init: add persistent instance-id mode Yuri Konotopov
2026-04-25 12:31 ` Yuri Konotopov [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260425123125.797431-4-ykonotopov@gnome.org \
--to=ykonotopov@gnome.org \
--cc=pve-devel@lists.proxmox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox