From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 6111875A7B for ; Tue, 13 Jul 2021 14:26:47 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 5750622B14 for ; Tue, 13 Jul 2021 14:26:17 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 2FB5122B06 for ; Tue, 13 Jul 2021 14:26:16 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 0A68E4102B for ; Tue, 13 Jul 2021 14:26:16 +0200 (CEST) From: Fabian Ebner To: pmg-devel@lists.proxmox.com Date: Tue, 13 Jul 2021 14:26:09 +0200 Message-Id: <20210713122610.72675-1-f.ebner@proxmox.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.511 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [proxmox.com] Subject: [pmg-devel] [PATCH pmg-gui 1/2] dashboard: add node info panel X-BeenThere: pmg-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Mail Gateway development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Jul 2021 12:26:47 -0000 Essentially the same as in PBS, but needed to use 'rootfs' instead of 'root' for the disk usage, avoid 'cpu' as an itemId (already used by the cluster resources), and get rid of the fingerprint button. Also added the link to the repositories panel like in Dominik's pending patch for PBS. Rename the existing resources panel to clarify what it actually is. Signed-off-by: Fabian Ebner --- Depends on the APT repo patches: https://lists.proxmox.com/pipermail/pmg-devel/2021-July/001796.html js/Dashboard.js | 35 +++++++- js/Makefile | 1 + js/dashboard/NodeInfo.js | 187 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 js/dashboard/NodeInfo.js diff --git a/js/Dashboard.js b/js/Dashboard.js index c92b2f0..79817b3 100644 --- a/js/Dashboard.js +++ b/js/Dashboard.js @@ -140,6 +140,8 @@ Ext.define('PMG.Dashboard', { var subscriptionPanel = me.lookup('subscription'); subscriptionPanel.setSubStatus(subStatus); + me.lookup('nodeInfo').setSubscriptionStatus(subStatus); + cpu = cpu/count; mem = mem/count; hd = hd/count; @@ -163,6 +165,15 @@ Ext.define('PMG.Dashboard', { } }, + updateRepositoryStatus: function(store, records, success) { + if (!success) { + return; + } + + let me = this; + me.lookup('nodeInfo').setRepositoryInfo(records[0].data['standard-repos']); + }, + init: function(view) { var me = this; var sp = Ext.state.Manager.getProvider(); @@ -272,6 +283,21 @@ Ext.define('PMG.Dashboard', { { type: 'string', name: 'receiver' }, ], }, + repositories: { + storeid: 'dash-repositories', + type: 'update', + interval: 15000, + autoStart: true, + autoLoad: true, + autoDestroy: true, + proxy: { + type: 'proxmox', + url: '/api2/json/nodes/localhost/apt/repositories', + }, + listeners: { + load: 'updateRepositoryStatus', + }, + }, }, }, @@ -385,7 +411,7 @@ Ext.define('PMG.Dashboard', { { height: 250, iconCls: 'fa fa-tasks', - title: gettext('Node Resources'), + title: gettext('Cluster Resources (average)'), bodyPadding: '0 20 0 20', layout: { type: 'hbox', @@ -411,6 +437,13 @@ Ext.define('PMG.Dashboard', { }, ], }, + { + xtype: 'pmgNodeInfoPanel', + reference: 'nodeInfo', + height: 250, + bodyPadding: '10 5 10 5', + iconCls: 'fa fa-tasks', + }, { height: 250, iconCls: 'fa fa-list', diff --git a/js/Makefile b/js/Makefile index 43d3ad8..f1ea2c7 100644 --- a/js/Makefile +++ b/js/Makefile @@ -27,6 +27,7 @@ JSSRC= \ QuarantineView.js \ Dashboard.js \ dashboard/MailProcessing.js \ + dashboard/NodeInfo.js \ dashboard/SubscriptionInfo.js \ dashboard/MiniGraph.js \ VersionInfo.js \ diff --git a/js/dashboard/NodeInfo.js b/js/dashboard/NodeInfo.js new file mode 100644 index 0000000..c286558 --- /dev/null +++ b/js/dashboard/NodeInfo.js @@ -0,0 +1,187 @@ +Ext.define('PMG.NodeInfoPanel', { + extend: 'Proxmox.panel.StatusView', + alias: 'widget.pmgNodeInfoPanel', + + layout: { + type: 'table', + columns: 2, + tableAttrs: { + style: { + width: '100%', + }, + }, + }, + + defaults: { + xtype: 'pmxInfoWidget', + padding: '0 10 5 10', + }, + + viewModel: { + data: { + subscriptionActive: '', + noSubscriptionRepo: '', + enterpriseRepo: '', + testRepo: '', + }, + formulas: { + repoStatus: function(get) { + if (get('subscriptionActive') === '' || get('enterpriseRepo') === '') { + return ''; + } + + if (get('noSubscriptionRepo') || get('testRepo')) { + return 'non-production'; + } else if (get('subscriptionActive') && get('enterpriseRepo')) { + return 'ok'; + } else if (!get('subscriptionActive') && get('enterpriseRepo')) { + return 'no-sub'; + } else if (!get('enterpriseRepo') || !get('noSubscriptionRepo') || !get('testRepo')) { + return 'no-repo'; + } + return 'unknown'; + }, + repoStatusMessage: function(get) { + const status = get('repoStatus'); + let repoLink = ` + + `; + return Proxmox.Utils.formatNodeRepoStatus(status, 'Proxmox Mail Gateway') + repoLink; + }, + }, + }, + + items: [ + { + itemId: 'nodecpu', + iconCls: 'fa fa-fw pmx-itype-icon-processor pmx-icon', + title: gettext('CPU usage'), + valueField: 'cpu', + maxField: 'cpuinfo', + renderer: Proxmox.Utils.render_node_cpu_usage, + }, + { + itemId: 'wait', + iconCls: 'pmx-icon-size fa fa-fw fa-clock-o', + title: gettext('IO delay'), + valueField: 'wait', + }, + { + xtype: 'box', + colspan: 2, + padding: '0 0 20 0', + }, + { + iconCls: 'fa fa-fw pmx-itype-icon-memory pmx-icon', + itemId: 'memory', + title: gettext('RAM usage'), + valueField: 'memory', + maxField: 'memory', + renderer: Proxmox.Utils.render_node_size_usage, + }, + { + itemId: 'load', + iconCls: 'pmx-icon-size fa fa-fw fa-tasks', + title: gettext('Load average'), + printBar: false, + textField: 'loadavg', + }, + { + iconCls: 'pmx-icon-size fa fa-fw fa-hdd-o', + itemId: 'rootfs', + title: gettext('HD space') + ' (root)', + valueField: 'rootfs', + maxField: 'rootfs', + renderer: Proxmox.Utils.render_node_size_usage, + }, + { + iconCls: 'pmx-icon-size fa fa-fw fa-refresh', + itemId: 'swap', + printSize: true, + title: gettext('SWAP usage'), + valueField: 'swap', + maxField: 'swap', + renderer: Proxmox.Utils.render_node_size_usage, + }, + { + xtype: 'box', + colspan: 2, + padding: '0 0 20 0', + }, + { + itemId: 'cpus', + colspan: 2, + printBar: false, + title: gettext('CPU(s)'), + textField: 'cpuinfo', + renderer: Proxmox.Utils.render_cpu_model, + value: '', + }, + { + itemId: 'kversion', + colspan: 2, + title: gettext('Kernel Version'), + printBar: false, + textField: 'kversion', + value: '', + }, + { + itemId: 'repositoryStatus', + colspan: 2, + printBar: false, + title: gettext('Repository Status'), + setValue: function(value) { // for binding below + this.updateValue(value); + }, + bind: { + value: '{repoStatusMessage}', + }, + }, + ], + + updateTitle: function() { + var me = this; + var uptime = Proxmox.Utils.render_uptime(me.getRecordValue('uptime')); + me.setTitle(Proxmox.NodeName + ' (' + gettext('Uptime') + ': ' + uptime + ')'); + }, + + setRepositoryInfo: function(standardRepos) { + let me = this; + let vm = me.getViewModel(); + + for (const standardRepo of standardRepos) { + const handle = standardRepo.handle; + const status = standardRepo.status; + + if (handle === "enterprise") { + vm.set('enterpriseRepo', status); + } else if (handle === "no-subscription") { + vm.set('noSubscriptionRepo', status); + } else if (handle === "test") { + vm.set('testRepo', status); + } + } + }, + + setSubscriptionStatus: function(status) { + let me = this; + let vm = me.getViewModel(); + + vm.set('subscriptionActive', status); + }, + + initComponent: function() { + let me = this; + + me.rstore = Ext.create('Proxmox.data.ObjectStore', { + interval: 3000, + url: '/api2/json/nodes/localhost/status', + autoStart: true, + }); + + me.callParent(); + + me.on('destroy', function() { me.rstore.stopUpdate(); }); + }, +}); -- 2.30.2