public inbox for pve-devel@lists.proxmox.com
 help / color / mirror / Atom feed
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




      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
Service provided by Proxmox Server Solutions GmbH | Privacy | Legal