From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 6D8E61FF15F for ; Mon, 2 Dec 2024 11:47:00 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 51AB314941; Mon, 2 Dec 2024 11:47:03 +0100 (CET) From: Gabriel Goller To: pve-devel@lists.proxmox.com Date: Mon, 2 Dec 2024 11:46:26 +0100 Message-Id: <20241202104626.166056-3-g.goller@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241202104626.166056-1-g.goller@proxmox.com> References: <20241202104626.166056-1-g.goller@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL -0.038 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pve-devel] [PATCH manager 2/2] lxc: show IPs in summary view X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox VE development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pve-devel-bounces@lists.proxmox.com Sender: "pve-devel" modelled after the QEMU Guest Agent UI. We only show the first non-loopback IP on the summary page itself. Originally-by: Leo Nunner [GG: increase status panel height] Signed-off-by: Gabriel Goller --- www/manager6/Makefile | 1 + www/manager6/lxc/ContainerIPView.js | 194 ++++++++++++++++++++++++++ www/manager6/panel/GuestStatusView.js | 12 +- www/manager6/panel/GuestSummary.js | 2 +- 4 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 www/manager6/lxc/ContainerIPView.js diff --git a/www/manager6/Makefile b/www/manager6/Makefile index c94a5cdfbf70..203a9d19cefc 100644 --- a/www/manager6/Makefile +++ b/www/manager6/Makefile @@ -201,6 +201,7 @@ JSSRC= \ lxc/ResourceEdit.js \ lxc/Resources.js \ lxc/MultiMPEdit.js \ + lxc/ContainerIPView.js \ menu/MenuItem.js \ menu/TemplateMenu.js \ ceph/CephInstallWizard.js \ diff --git a/www/manager6/lxc/ContainerIPView.js b/www/manager6/lxc/ContainerIPView.js new file mode 100644 index 000000000000..69b107af3243 --- /dev/null +++ b/www/manager6/lxc/ContainerIPView.js @@ -0,0 +1,194 @@ +Ext.define('PVE.window.ContainerIPInfo', { + extend: 'Ext.window.Window', + width: 600, + title: gettext('Container Network Information'), + height: 300, + layout: { + type: 'fit', + }, + modal: true, + items: [ + { + xtype: 'grid', + store: {}, + emptyText: gettext('No network information'), + columns: [ + { + dataIndex: 'name', + text: gettext('Name'), + flex: 2, + }, + { + dataIndex: 'hwaddr', + text: gettext('MAC address'), + width: 140, + }, + { + dataIndex: 'inet', + text: gettext('IPv4 address'), + align: 'right', + flex: 3, + }, + { + dataIndex: 'inet6', + text: gettext('IPv6 address'), + align: 'right', + flex: 4, + }, + ], + }, + ], +}); + +Ext.define('PVE.lxc.IPView', { + extend: 'Ext.container.Container', + xtype: 'pveContainerIPView', + + layout: { + type: 'hbox', + align: 'top', + }, + + items: [ + { + xtype: 'box', + html: ' IPs', + }, + { + xtype: 'container', + flex: 1, + layout: { + type: 'vbox', + align: 'right', + pack: 'end', + }, + items: [ + { + xtype: 'label', + flex: 1, + itemId: 'ipBox', + style: { + 'text-align': 'right', + }, + }, + { + xtype: 'button', + itemId: 'moreBtn', + hidden: true, + ui: 'default-toolbar', + handler: function(btn) { + let view = this.up('pveContainerIPView'); + + var win = Ext.create('PVE.window.ContainerIPInfo'); + win.down('grid').getStore().setData(view.ifaces); + win.show(); + }, + text: gettext('More'), + }, + ], + }, + ], + + getDefaultIps: function(ifaces) { + var me = this; + var ips = []; + ifaces.forEach(function(iface) { + // We only want to show the first non-loopback interface + if (!ips.length && + iface.data.hwaddr && + iface.data.hwaddr !== '00:00:00:00:00:00' && + iface.data.hwaddr !== '0:0:0:0:0:0') { + ips.push(iface.data.inet); + ips.push(iface.data.inet6); + } + }); + + return ips; + }, + + startIPStore: function(store, records, success) { + var me = this; + let state = store.getById('status'); + + me.running = state && state.data.value === 'running'; + + var caps = Ext.state.Manager.get('GuiCap'); + + if (!caps.vms['VM.Monitor']) { + var errorText = gettext("Requires '{0}' Privileges"); + me.updateStatus(false, Ext.String.format(errorText, 'VM.Monitor')); + return; + } + + if (me.running && me.ipStore.isStopped) { + me.ipStore.startUpdate(); + } else if (me.ipStore.isStopped) { + me.updateStatus(); + } + }, + + updateStatus: function(unsuccessful, defaulttext) { + var me = this; + var text = defaulttext || gettext('No network information'); + var more = false; + if (Ext.isArray(me.ifaces) && me.ifaces.length) { + more = true; + var ips = me.getDefaultIps(me.ifaces); + if (ips.length !== 0) { + text = ips.join('
'); + } + } + + var ipBox = me.down('#ipBox'); + ipBox.update(text); + + var moreBtn = me.down('#moreBtn'); + moreBtn.setVisible(more); + }, + + initComponent: function() { + var me = this; + + if (!me.rstore) { + throw 'rstore not given'; + } + + if (!me.pveSelNode) { + throw 'pveSelNode not given'; + } + + var nodename = me.pveSelNode.data.node; + var vmid = me.pveSelNode.data.vmid; + + me.ipStore = Ext.create('Proxmox.data.UpdateStore', { + interval: 10000, + storeid: 'lxc-interfaces-' + vmid, + method: 'GET', + proxy: { + type: 'proxmox', + url: '/api2/json/nodes/' + nodename + '/lxc/' + vmid + '/interfaces', + }, + }); + + me.callParent(); + + me.mon(me.ipStore, 'load', function(store, records, success) { + if (records && records.length) { + me.ifaces = records; + } else { + me.ifaces = undefined; + } + me.updateStatus(!success); + }); + + me.on('destroy', me.ipStore.stopUpdate, me.ipStore); + + // if we already have info about the guest, use it immediately + if (me.rstore.getCount()) { + me.startIPStore(me.rstore, me.rstore.getData(), false); + } + + // check if the guest agent is there on every statusstore load + me.mon(me.rstore, 'load', me.startIPStore, me); + }, +}); diff --git a/www/manager6/panel/GuestStatusView.js b/www/manager6/panel/GuestStatusView.js index 6401811c73bb..250c7ed117fa 100644 --- a/www/manager6/panel/GuestStatusView.js +++ b/www/manager6/panel/GuestStatusView.js @@ -146,7 +146,7 @@ Ext.define('PVE.panel.GuestStatusView', { height: 15, }, { - itemId: 'ips', + itemId: 'agentIPs', xtype: 'pveAgentIPView', cbind: { rstore: '{rstore}', @@ -155,6 +155,16 @@ Ext.define('PVE.panel.GuestStatusView', { disabled: '{isLxc}', }, }, + { + itemId: 'ctIPS', + xtype: 'pveContainerIPView', + cbind: { + rstore: '{rstore}', + pveSelNode: '{pveSelNode}', + hidden: '{!isLxc}', + disabled: '{!isLxc}', + }, + }, ], updateTitle: function() { diff --git a/www/manager6/panel/GuestSummary.js b/www/manager6/panel/GuestSummary.js index 1565db3f658d..2186967f62da 100644 --- a/www/manager6/panel/GuestSummary.js +++ b/www/manager6/panel/GuestSummary.js @@ -54,7 +54,7 @@ Ext.define('PVE.guest.Summary', { items = [ { xtype: 'container', - height: 300, + height: 370, layout: { type: 'hbox', align: 'stretch', -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel