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 598197531D for ; Wed, 23 Jun 2021 18:11:32 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 4F18DE541 for ; Wed, 23 Jun 2021 18:11:32 +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) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 6B6CCE535 for ; Wed, 23 Jun 2021 18:11:30 +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 3682D46764 for ; Wed, 23 Jun 2021 18:11:30 +0200 (CEST) From: Fabian Ebner To: pve-devel@lists.proxmox.com Date: Wed, 23 Jun 2021 18:11:26 +0200 Message-Id: <20210623161126.218308-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.658 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 Subject: [pve-devel] [PATCH manager] ui: node summary: show repository configuration status 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: , X-List-Received-Date: Wed, 23 Jun 2021 16:11:32 -0000 I tried to use itemid and lookupreference for the nodeStatus item, but couldn't get it to work, so I factored it out. Signed-off-by: Fabian Ebner --- Depends on the APT repositories API/UI series. https://lists.proxmox.com/pipermail/pve-devel/2021-June/048963.html www/manager6/node/StatusView.js | 102 ++++++++++++++++++++++++++++++++ www/manager6/node/Summary.js | 49 +++++++++++++-- 2 files changed, 145 insertions(+), 6 deletions(-) diff --git a/www/manager6/node/StatusView.js b/www/manager6/node/StatusView.js index 564658c4..f4a55d14 100644 --- a/www/manager6/node/StatusView.js +++ b/www/manager6/node/StatusView.js @@ -2,6 +2,69 @@ Ext.define('PVE.node.StatusView', { extend: 'Proxmox.panel.StatusView', alias: 'widget.pveNodeStatus', + viewModel: { + data: { + subscriptionActive: '', + noSubscriptionRepo: '', + enterpriseRepo: '', + testRepo: '', + }, + formulas: { + repoStatus: function(get) { + if (get('subscriptionActive') === '' || + get('enterpriseRepo') === '') { + return ''; + } + + if (!get('subscriptionActive') && get('enterpriseRepo')) { + return 'no-sub'; + } + + if (get('noSubscriptionRepo') || get('testRepo')) { + return 'non-production'; + } + + if (!get('enterpriseRepo') || !get('noSubscriptionRepo') || !get('testRepo')) { + return 'no-repo'; + } + + return 'ok'; + }, + repoStatusMessage: function(get) { + const status = get('repoStatus'); + + if (status === 'ok') { + return gettext('Enterprise repository and subscription active'); + } else if (status === 'no-sub') { + return gettext('Enterprise repository enabled, but no active subscription'); + } else if (status === 'non-production') { + return gettext('No-subscription or test repository in use'); + } else if (status === 'no-repo') { + return gettext('No PVE repository is enabled!'); + } + + return Proxmox.Utils.unknownText; + }, + repoStatusIconCls: function(get) { + const status = get('repoStatus'); + + let iconCls = (cls) => `fa fa-fw ${cls}`; + + if (status === 'ok') { + return iconCls('fa-check good'); + } else if (status === 'no-sub') { + return iconCls('fa-exclamation-triangle critical'); + } else if (status === 'non-production') { + return iconCls('fa-exclamation-triangle warning'); + } else if (status === 'no-repo') { + return iconCls('fa-exclamation-triangle critical'); + } + + return iconCls('fa-question-circle-o'); + }, + }, + }, + height: 300, bodyPadding: '20 15 20 15', @@ -113,6 +176,21 @@ Ext.define('PVE.node.StatusView', { textField: 'pveversion', value: '', }, + { + itemId: 'repositoryStatus', + colspan: 2, + printBar: false, + title: gettext('Repository Configuration Status'), + // for bind + setValue: function(value) { + let me = this; + me.updateValue(value); + }, + bind: { + iconCls: '{repoStatusIconCls}', + value: '{repoStatusMessage}', + }, + }, ], updateTitle: function() { @@ -121,4 +199,28 @@ Ext.define('PVE.node.StatusView', { me.setTitle(me.pveSelNode.data.node + ' (' + 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); + }, }); diff --git a/www/manager6/node/Summary.js b/www/manager6/node/Summary.js index 1c93ef04..f3709dfc 100644 --- a/www/manager6/node/Summary.js +++ b/www/manager6/node/Summary.js @@ -83,6 +83,38 @@ Ext.define('PVE.node.Summary', { }); }, + updateRepositoryStatus: function() { + let me = this; + let nodeStatus = me.nodeStatus; + + let nodename = me.pveSelNode.data.node; + + Proxmox.Utils.API2Request({ + url: `/nodes/${nodename}/apt/repositories`, + method: 'GET', + failure: function(response, opts) { + Ext.Msg.alert(gettext('Error'), response.htmlStatus); + }, + success: function(response, opts) { + nodeStatus.setRepositoryInfo(response.result.data['standard-repos']); + }, + }); + + Proxmox.Utils.API2Request({ + url: `/nodes/${nodename}/subscription`, + method: 'GET', + failure: function(response, opts) { + Ext.Msg.alert(gettext('Error'), response.htmlStatus); + }, + success: function(response, opts) { + const res = response.result; + const subscription = !(res === null || res === undefined || + !res || res.data.status.toLowerCase() !== 'active'); + nodeStatus.setSubscriptionStatus(subscription); + }, + }); + }, + initComponent: function() { var me = this; @@ -109,8 +141,16 @@ Ext.define('PVE.node.Summary', { model: 'pve-rrd-node', }); + let nodeStatus = Ext.create('PVE.node.StatusView', { + xtype: 'pveNodeStatus', + rstore: rstore, + width: 770, + pveSelNode: me.pveSelNode, + }); + Ext.apply(me, { tbar: [version_btn, '->', { xtype: 'proxmoxRRDTypeSelector' }], + nodeStatus: nodeStatus, items: [ { xtype: 'container', @@ -123,12 +163,7 @@ Ext.define('PVE.node.Summary', { columnWidth: 1, }, items: [ - { - xtype: 'pveNodeStatus', - rstore: rstore, - width: 770, - pveSelNode: me.pveSelNode, - }, + nodeStatus, { xtype: 'proxmoxRRDChart', title: gettext('CPU usage'), @@ -179,6 +214,8 @@ Ext.define('PVE.node.Summary', { }, }); + me.updateRepositoryStatus(); + me.callParent(); let sp = Ext.state.Manager.getProvider(); -- 2.30.2