[pve-devel] [PATCH manager v5 3/4] fix #1926 ui: vm console: autodetect novnc or xtermjs
Dominik Csapak
d.csapak at proxmox.com
Tue Apr 8 10:08:10 CEST 2025
tiny nits inline,
with or without that, consider this
Reviewed-by: Dominik Csapak <d.csapak at proxmox.com>
On 4/7/25 18:27, Aaron Lauterer wrote:
> Some users configure their VMs to use serial as their display. The big
> benefit is that in combination with the xtermjs remote console, copy &
> paste works a lot better than via novnc.
>
> While the console button in the top right allows to manually choose the
> console type, the Console in the main submenu of a VM does not.
>
> This patch changes the behavior to not load the console right away if
> set to 'kvm'. Instead, the callback from the VM's status/current call
> will run the final steps to load the console. Because then we know if it
> should be noVNC or xtermjs.
>
> That means that in the VNCConsole component we need to keep track if the
> console has been fully set up and is running. The actual code that loads
> the console into the iframe is moved into a function, so we cann call it
> from the API callback.
>
> One result is that the behavior changes. Loading the console on a VM
> will take a little bit longer:
> * When then Console is the selected and one switches between VMs, a new
> status/current call is made and on a good connection, the console
> should load just a few moments later.
> * When one switches to the console from another submenu of the VM, the
> console will load once the next API call to status/current finished.
>
> Signed-off-by: Aaron Lauterer <a.lauterer at proxmox.com>
> ---
> Overall not really less complex than v4 [0] but with the new display
> property definitely more ready to changes in the future and we save one
> API call.
>
> [0] https://lore.proxmox.com/pve-devel/20250325091854.1051956-1-a.lauterer@proxmox.com/
>
> changes since:
> v4:
> * use new status/current display property
>
> v3:
> * fixed spacing issues
> * add 'current' parameter when fetching config as the pending might have
> a different display set
>
> v2:
> * change approach and do it in the UI alone by fetching the VM
> config before deciding which console to use
>
> v1:
> * set 'autodetect' to always true in 'VNCConsole.js'
> * add additional checks in pveproxy
> * only if autodetect is enabled and console is set to 'kvm'
> * username exists and has VM.Console permissions for the guest
>
>
>
> www/manager6/VNCConsole.js | 52 +++++++++++++++++++++++++------------
> www/manager6/qemu/Config.js | 8 +++++-
> 2 files changed, 42 insertions(+), 18 deletions(-)
>
> diff --git a/www/manager6/VNCConsole.js b/www/manager6/VNCConsole.js
> index 9057e447..3371c923 100644
> --- a/www/manager6/VNCConsole.js
> +++ b/www/manager6/VNCConsole.js
> @@ -12,6 +12,36 @@ Ext.define('PVE.noVncConsole', {
> layout: 'fit',
> border: false,
>
> + setupDone: false, // initial setup is done and the session is running
> +
> + loadConsole: function(xtermjs, consoleType) {
> + let me = this;
> + if (me.setupDone) {
> + return;
> + }
> +
> + let type = xtermjs ? 'xtermjs' : 'novnc';
> + let sp = Ext.state.Manager.getProvider();
> + if (Ext.isFunction(me.beforeLoad)) {
> + me.beforeLoad();
> + }
> + let queryDict = {
> + console: consoleType, // kvm, lxc, upgrade or shell
> + vmid: me.vmid,
> + node: me.nodename,
> + cmd: me.cmd,
> + 'cmd-opts': me.cmdOpts,
> + resize: sp.get('novnc-scaling', 'scale'),
> + };
> + let box = this.down('[itemid=vncconsole]');
> + queryDict[type] = 1;
> + PVE.Utils.cleanEmptyObjectKeys(queryDict);
> + let url = '/?' + Ext.Object.toQueryString(queryDict);
> + Proxmox.Utils.setErrorMask(me);
> + box.load(url);
> + me.setupDone = true;
> + },
> +
> initComponent: function() {
> var me = this;
>
> @@ -29,37 +59,25 @@ Ext.define('PVE.noVncConsole', {
>
> // always use same iframe, to avoid running several noVnc clients
> // at same time (to avoid performance problems)
> - var box = Ext.create('Ext.ux.IFrame', { itemid: "vncconsole" });
> + let box = Ext.create('Ext.ux.IFrame', { itemid: "vncconsole" });
>
> - var type = me.xtermjs ? 'xtermjs' : 'novnc';
> Ext.apply(me, {
> items: box,
> listeners: {
> activate: function() {
> - let sp = Ext.state.Manager.getProvider();
> - if (Ext.isFunction(me.beforeLoad)) {
> - me.beforeLoad();
> + if (me.consoleType !== 'kvm') {
> + me.loadConsole(me.xtermjs, me.consoleType);
> }
> - let queryDict = {
> - console: me.consoleType, // kvm, lxc, upgrade or shell
> - vmid: me.vmid,
> - node: me.nodename,
> - cmd: me.cmd,
> - 'cmd-opts': me.cmdOpts,
> - resize: sp.get('novnc-scaling', 'scale'),
> - };
> - queryDict[type] = 1;
> - PVE.Utils.cleanEmptyObjectKeys(queryDict);
> - var url = '/?' + Ext.Object.toQueryString(queryDict);
> - box.load(url);
> },
> },
> });
>
> +
> me.callParent();
>
> me.on('afterrender', function() {
> me.focus();
> + Proxmox.Utils.setErrorMask(me, true);
> });
> },
>
> diff --git a/www/manager6/qemu/Config.js b/www/manager6/qemu/Config.js
> index 0699175e..03692abe 100644
> --- a/www/manager6/qemu/Config.js
> +++ b/www/manager6/qemu/Config.js
> @@ -5,6 +5,8 @@ Ext.define('PVE.qemu.Config', {
> onlineHelp: 'chapter_virtual_machines',
> userCls: 'proxmox-tags-full',
>
> + referenceHolder: true,
> +
> initComponent: function() {
> var me = this;
> var vm = me.pveSelNode.data;
> @@ -283,6 +285,7 @@ Ext.define('PVE.qemu.Config', {
> vmid: vmid,
> consoleType: 'kvm',
> nodename: nodename,
> + reference: 'submenuConsoleBtn',
> });
> }
>
> @@ -444,7 +447,8 @@ Ext.define('PVE.qemu.Config', {
> lock = rec ? rec.data.value : undefined;
>
> spice = !!s.data.get('spice');
> - xtermjs = !!s.data.get('serial');
> + rec = s.data.get('display');
> + xtermjs = rec ? rec.data.value.type.startsWith('serial') : false;
two tiny things here:
* rec is imho not a good name for the display portion, you could just name it 'display'
* for the result of xtermjs you could use something like:
xtermjs = rec?.data.value.type.startsWith('serial') ?? false;
instead of the ternary operator
> }
>
> rec = s.data.get('tags');
> @@ -467,6 +471,8 @@ Ext.define('PVE.qemu.Config', {
> consoleBtn.setEnableSpice(spice);
> consoleBtn.setEnableXtermJS(xtermjs);
>
> + me.lookup('submenuConsoleBtn')?.loadConsole(xtermjs, 'kvm');
> +
> statusTxt.update({ lock: lock });
>
> let guest_running = status === 'running' &&
More information about the pve-devel
mailing list