From 2e1cd0e1f56a6bc60e59d216c30ee9704e9062a6 Mon Sep 17 00:00:00 2001 From: Meliox Date: Mon, 8 Jun 2026 21:03:41 +0200 Subject: [PATCH] Start patching --- .../patches/01-proxmoxlib-js-nagscreen.patch | 0 .../patches/01-nodes-pm-sensors.patch | 15 + .../patches/02-nodes-pm-GPU-RRD-history.patch | 0 .../patches/03-pvemanager-js-sensors.patch | 1013 +++++++++++++++++ 4 files changed, 1028 insertions(+) create mode 100644 src/NagScreen/patches/01-proxmoxlib-js-nagscreen.patch create mode 100644 src/PVENodeInfo/patches/01-nodes-pm-sensors.patch create mode 100644 src/PVENodeInfo/patches/02-nodes-pm-GPU-RRD-history.patch create mode 100644 src/PVENodeInfo/patches/03-pvemanager-js-sensors.patch diff --git a/src/NagScreen/patches/01-proxmoxlib-js-nagscreen.patch b/src/NagScreen/patches/01-proxmoxlib-js-nagscreen.patch new file mode 100644 index 0000000..e69de29 diff --git a/src/PVENodeInfo/patches/01-nodes-pm-sensors.patch b/src/PVENodeInfo/patches/01-nodes-pm-sensors.patch new file mode 100644 index 0000000..272e6f8 --- /dev/null +++ b/src/PVENodeInfo/patches/01-nodes-pm-sensors.patch @@ -0,0 +1,15 @@ +--- usr/share/perl5/PVE/API2/Nodes.pm 2026-05-24 02:05:58.000000000 +0200 ++++ /usr/share/perl5/PVE/API2/Nodes.pm 2026-06-08 20:38:56.988900119 +0200 +@@ -536,6 +536,12 @@ + + $res->{pveversion} = PVE::pvecfg::package() . "/" . PVE::pvecfg::version_text(); + ++ # Collect sensor data from PveMod_SensorInfo ++ use PVE::API2::PVEMod_SensorInfo; ++ $res->{PveMod_JsonSensorInfo} = PVE::API2::PVEMod_SensorInfo::get_sensors_info(); ++ $res->{PveMod_Version} = PVE::API2::PVEMod_SensorInfo::get_pve_mod_version(); ++ $res->{PveMod_upsInfo} = PVE::API2::PVEMod_SensorInfo::get_ups_info(); ++ $res->{PveMod_systemInfo} = PVE::API2::PVEMod_SensorInfo::get_system_info(); + my $dinfo = df('/', 1); # output is bytes + + $res->{rootfs} = { diff --git a/src/PVENodeInfo/patches/02-nodes-pm-GPU-RRD-history.patch b/src/PVENodeInfo/patches/02-nodes-pm-GPU-RRD-history.patch new file mode 100644 index 0000000..e69de29 diff --git a/src/PVENodeInfo/patches/03-pvemanager-js-sensors.patch b/src/PVENodeInfo/patches/03-pvemanager-js-sensors.patch new file mode 100644 index 0000000..0252331 --- /dev/null +++ b/src/PVENodeInfo/patches/03-pvemanager-js-sensors.patch @@ -0,0 +1,1013 @@ +--- usr/share/pve-manager/js/pvemanagerlib.js 2026-05-24 02:05:58.000000000 +0200 ++++ /usr/share/pve-manager/js/pvemanagerlib.js 2026-06-07 15:44:28.581927600 +0200 +@@ -50737,175 +50737,181 @@ + me.reload(); + }, + }); +-Ext.define('PVE.node.StatusView', { +- extend: 'Proxmox.panel.StatusView', +- alias: 'widget.pveNodeStatus', +- +- height: 350, +- bodyPadding: '15 5 15 5', +- +- layout: { +- type: 'table', +- columns: 2, +- tableAttrs: { +- style: { +- width: '100%', +- }, +- }, +- }, +- +- defaults: { +- xtype: 'pmxInfoWidget', +- padding: '0 10 5 10', +- }, +- +- items: [ +- { +- itemId: 'cpu', +- 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: 'fa fa-fw fa-clock-o', +- title: gettext('IO delay'), +- valueField: 'wait', +- rowspan: 2, +- }, +- { +- itemId: 'load', +- iconCls: 'fa fa-fw fa-tasks', +- title: gettext('Load average'), +- printBar: false, +- textField: 'loadavg', +- }, +- { +- 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', +- warningThreshold: 0.9, +- criticalThreshold: 0.975, +- // TODO: split out ARC usage +- renderer: Proxmox.Utils.render_node_size_usage, +- }, +- { +- itemId: 'ksm', +- printBar: false, +- title: gettext('KSM sharing'), +- textField: 'ksm', +- renderer: (record) => Proxmox.Utils.render_size(record.shared), +- padding: '0 10 10 10', +- }, +- { +- iconCls: 'fa fa-fw fa-hdd-o', +- itemId: 'rootfs', +- title: '/ ' + gettext('HD space'), +- valueField: 'rootfs', +- maxField: 'rootfs', +- renderer: Proxmox.Utils.render_node_size_usage, +- }, +- { +- iconCls: '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: '', +- }, +- { +- colspan: 2, +- title: gettext('Kernel Version'), +- printBar: false, +- // TODO: remove with next major and only use newish current-kernel textfield +- multiField: true, +- //textField: 'current-kernel', +- renderer: ({ data }) => { +- if (!data['current-kernel']) { +- return data.kversion; +- } +- let kernel = data['current-kernel']; +- let buildDate = kernel.version.match(/\((.+)\)\s*$/)?.[1] ?? 'unknown'; +- return `${kernel.sysname} ${kernel.release} (${buildDate})`; +- }, +- value: '', +- }, +- { +- colspan: 2, +- title: gettext('Boot Mode'), +- printBar: false, +- textField: 'boot-info', +- renderer: (boot) => { +- if (boot.mode === 'legacy-bios') { +- return 'Legacy BIOS'; +- } else if (boot.mode === 'efi') { +- return `EFI${boot.secureboot ? ' (Secure Boot)' : ''}`; +- } +- return Proxmox.Utils.unknownText; +- }, +- value: '', +- }, +- { +- itemId: 'version', +- colspan: 2, +- printBar: false, +- title: gettext('Manager Version'), +- textField: 'pveversion', +- value: '', +- }, +- ], +- +- updateTitle: function () { +- var me = this; +- var uptime = Proxmox.Utils.render_uptime(me.getRecordValue('uptime')); +- me.setTitle(me.pveSelNode.data.node + ' (' + gettext('Uptime') + ': ' + uptime + ')'); +- }, +- +- initComponent: function () { +- let me = this; +- +- let stateProvider = Ext.state.Manager.getProvider(); +- let repoLink = stateProvider.encodeHToken({ +- view: 'server', +- rid: `node/${me.pveSelNode.data.node}`, +- ltab: 'tasks', +- nodetab: 'aptrepositories', +- }); +- +- me.items.push({ +- xtype: 'pmxNodeInfoRepoStatus', +- itemId: 'repositoryStatus', +- product: 'Proxmox VE', +- repoLink: `#${repoLink}`, +- }); +- +- me.callParent(); +- }, ++// Load custom PVE.node.StatusView from external module ++Ext.Loader.loadScript({ ++ url: '/pve2/js/PveMod_PveNodeStatusView.js', ++ onLoad: function() { }, ++ onError: function() { console.error('Failed to load PveMod_PveNodeStatusView.js'); } + }); ++// Ext.define('PVE.node.StatusView', { ++// extend: 'Proxmox.panel.StatusView', ++// alias: 'widget.pveNodeStatus', ++// ++// height: 350, ++// bodyPadding: '15 5 15 5', ++// ++// layout: { ++// type: 'table', ++// columns: 2, ++// tableAttrs: { ++// style: { ++// width: '100%', ++// }, ++// }, ++// }, ++// ++// defaults: { ++// xtype: 'pmxInfoWidget', ++// padding: '0 10 5 10', ++// }, ++// ++// items: [ ++// { ++// itemId: 'cpu', ++// 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: 'fa fa-fw fa-clock-o', ++// title: gettext('IO delay'), ++// valueField: 'wait', ++// rowspan: 2, ++// }, ++// { ++// itemId: 'load', ++// iconCls: 'fa fa-fw fa-tasks', ++// title: gettext('Load average'), ++// printBar: false, ++// textField: 'loadavg', ++// }, ++// { ++// 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', ++// warningThreshold: 0.9, ++// criticalThreshold: 0.975, ++// // TODO: split out ARC usage ++// renderer: Proxmox.Utils.render_node_size_usage, ++// }, ++// { ++// itemId: 'ksm', ++// printBar: false, ++// title: gettext('KSM sharing'), ++// textField: 'ksm', ++// renderer: (record) => Proxmox.Utils.render_size(record.shared), ++// padding: '0 10 10 10', ++// }, ++// { ++// iconCls: 'fa fa-fw fa-hdd-o', ++// itemId: 'rootfs', ++// title: '/ ' + gettext('HD space'), ++// valueField: 'rootfs', ++// maxField: 'rootfs', ++// renderer: Proxmox.Utils.render_node_size_usage, ++// }, ++// { ++// iconCls: '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: '', ++// }, ++// { ++// colspan: 2, ++// title: gettext('Kernel Version'), ++// printBar: false, ++// // TODO: remove with next major and only use newish current-kernel textfield ++// multiField: true, ++// //textField: 'current-kernel', ++// renderer: ({ data }) => { ++// if (!data['current-kernel']) { ++// return data.kversion; ++// } ++// let kernel = data['current-kernel']; ++// let buildDate = kernel.version.match(/\((.+)\)\s*$/)?.[1] ?? 'unknown'; ++// return `${kernel.sysname} ${kernel.release} (${buildDate})`; ++// }, ++// value: '', ++// }, ++// { ++// colspan: 2, ++// title: gettext('Boot Mode'), ++// printBar: false, ++// textField: 'boot-info', ++// renderer: (boot) => { ++// if (boot.mode === 'legacy-bios') { ++// return 'Legacy BIOS'; ++// } else if (boot.mode === 'efi') { ++// return `EFI${boot.secureboot ? ' (Secure Boot)' : ''}`; ++// } ++// return Proxmox.Utils.unknownText; ++// }, ++// value: '', ++// }, ++// { ++// itemId: 'version', ++// colspan: 2, ++// printBar: false, ++// title: gettext('Manager Version'), ++// textField: 'pveversion', ++// value: '', ++// }, ++// ], ++// ++// updateTitle: function () { ++// var me = this; ++// var uptime = Proxmox.Utils.render_uptime(me.getRecordValue('uptime')); ++// me.setTitle(me.pveSelNode.data.node + ' (' + gettext('Uptime') + ': ' + uptime + ')'); ++// }, ++// ++// initComponent: function () { ++// let me = this; ++// ++// let stateProvider = Ext.state.Manager.getProvider(); ++// let repoLink = stateProvider.encodeHToken({ ++// view: 'server', ++// rid: `node/${me.pveSelNode.data.node}`, ++// ltab: 'tasks', ++// nodetab: 'aptrepositories', ++// }); ++// ++// me.items.push({ ++// xtype: 'pmxNodeInfoRepoStatus', ++// itemId: 'repositoryStatus', ++// product: 'Proxmox VE', ++// repoLink: `#${repoLink}`, ++// }); ++// ++// me.callParent(); ++// }, ++// }); + Ext.define('PVE.node.SubscriptionKeyEdit', { + extend: 'Proxmox.window.Edit', + +@@ -51112,333 +51118,333 @@ + me.callParent(); + }, + }); +-Ext.define('PVE.node.Summary', { +- extend: 'Ext.panel.Panel', +- alias: 'widget.pveNodeSummary', +- +- scrollable: true, +- bodyPadding: 5, +- +- showVersions: function () { +- var me = this; +- +- // Note: we use simply text/html here, because ExtJS grid has problems +- // with cut&paste +- +- var nodename = me.pveSelNode.data.node; +- +- var view = Ext.createWidget('component', { +- autoScroll: true, +- id: 'pkgversions', +- padding: 5, +- style: { +- 'white-space': 'pre', +- 'font-family': 'monospace', +- }, +- }); +- +- var win = Ext.create('Ext.window.Window', { +- title: gettext('Package versions'), +- width: 600, +- height: 600, +- layout: 'fit', +- modal: true, +- items: [view], +- buttons: [ +- { +- xtype: 'button', +- iconCls: 'fa fa-clipboard', +- handler: function (button) { +- window +- .getSelection() +- .selectAllChildren(document.getElementById('pkgversions')); +- document.execCommand('copy'); +- }, +- text: gettext('Copy'), +- }, +- { +- text: gettext('Ok'), +- handler: function () { +- this.up('window').close(); +- }, +- }, +- ], +- }); +- +- Proxmox.Utils.API2Request({ +- waitMsgTarget: me, +- url: `/nodes/${nodename}/apt/versions`, +- method: 'GET', +- failure: function (response, opts) { +- win.close(); +- Ext.Msg.alert(gettext('Error'), response.htmlStatus); +- }, +- success: function (response, opts) { +- win.show(); +- let text = ''; +- Ext.Array.each(response.result.data, function (rec) { +- let version = 'not correctly installed'; +- let pkg = rec.Package; +- if (rec.OldVersion && rec.CurrentState === 'Installed') { +- version = rec.OldVersion; +- } +- if (rec.RunningKernel) { +- text += `${pkg}: ${version} (running kernel: ${rec.RunningKernel})\n`; +- } else if (rec.ManagerVersion) { +- text += `${pkg}: ${version} (running version: ${rec.ManagerVersion})\n`; +- } else { +- text += `${pkg}: ${version}\n`; +- } +- }); +- +- view.update(Ext.htmlEncode(text)); +- }, +- }); +- }, +- +- updateRepositoryStatus: function () { +- let me = this; +- let repoStatus = me.nodeStatus.down('#repositoryStatus'); +- +- let nodename = me.pveSelNode.data.node; +- +- Proxmox.Utils.API2Request({ +- url: `/nodes/${nodename}/apt/repositories`, +- method: 'GET', +- failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus), +- success: (response) => +- repoStatus.setRepositoryInfo(response.result.data['standard-repos']), +- }); +- +- Proxmox.Utils.API2Request({ +- url: `/nodes/${nodename}/subscription`, +- method: 'GET', +- failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus), +- success: function (response, opts) { +- const res = response.result; +- const subscription = res?.data?.status.toLowerCase() === 'active'; +- repoStatus.setSubscriptionStatus(subscription); +- }, +- }); +- }, +- +- initComponent: function () { +- var me = this; +- +- var nodename = me.pveSelNode.data.node; +- if (!nodename) { +- throw 'no node name specified'; +- } +- +- if (!me.statusStore) { +- throw 'no status storage specified'; +- } +- +- var rstore = me.statusStore; +- +- var version_btn = new Ext.Button({ +- text: gettext('Package versions'), +- handler: function () { +- Proxmox.Utils.checked_command(function () { +- me.showVersions(); +- }); +- }, +- }); +- +- var rrdstore = Ext.create('Proxmox.data.RRDStore', { +- rrdurl: '/api2/json/nodes/' + nodename + '/rrddata', +- 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', +- itemId: 'itemcontainer', +- layout: 'column', +- minWidth: 700, +- defaults: { +- minHeight: 360, +- padding: 5, +- columnWidth: 1, +- }, +- items: [ +- nodeStatus, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('CPU Usage'), +- fields: ['cpu', 'iowait'], +- fieldTitles: [gettext('CPU usage'), gettext('IO delay')], +- unit: 'percent', +- store: rrdstore, +- }, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('Server Load'), +- fields: ['loadavg'], +- fieldTitles: [gettext('Load average')], +- store: rrdstore, +- }, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('Memory usage'), +- fields: [ +- { +- yField: 'memtotal', +- title: gettext('Total'), +- tooltip: { +- trackMouse: true, +- renderer: function (toolTip, record, item) { +- let value = record.get('memtotal'); +- +- if (value === null) { +- toolTip.setHtml(gettext('No Data')); +- } else { +- let total = Proxmox.Utils.format_size(value); +- let time = new Date(record.get('time')); +- +- let avail = record.get('memavailable'); +- let availText = ''; +- if (Ext.isNumeric(avail)) { +- let v = Proxmox.Utils.format_size(avail); +- availText = ` (${gettext('Available')}: ${v})`; +- } +- +- toolTip.setHtml( +- `${gettext('Total')}: ${total}${availText}
${time}`, +- ); +- } +- }, +- }, +- }, +- { +- yField: 'memused', +- title: gettext('Used'), +- tooltip: { +- trackMouse: true, +- renderer: function (toolTip, record, item) { +- let value = record.get('memused'); +- +- if (value === null) { +- toolTip.setHtml(gettext('No Data')); +- } else { +- let total = Proxmox.Utils.format_size(value); +- let time = new Date(record.get('time')); +- +- let arc = record.get('arcsize'); +- let arcText = ''; +- if (Ext.isNumeric(arc) && arc > 1024 * 1024) { +- let v = Proxmox.Utils.format_size(value - arc); +- arcText = ` (${gettext('Without ZFS ARC')}: ${v})`; +- } +- +- toolTip.setHtml( +- `${gettext('Used')}: ${total}${arcText}
${time}`, +- ); +- } +- }, +- }, +- }, +- 'arcsize', +- { +- type: 'line', +- fill: false, +- yField: 'memavailable', +- title: gettext('Available'), +- style: { +- lineWidth: 2.5, +- opacity: 1, +- }, +- }, +- ], +- fieldTitles: [ +- gettext('Total'), +- gettext('Used'), +- gettext('ZFS ARC'), +- gettext('Available'), +- ], +- colors: ['#94ae0a', '#115fa6', '#24AD9A', '#bbde0d'], +- unit: 'bytes', +- powerOfTwo: true, +- store: rrdstore, +- }, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('Network Traffic'), +- fields: ['netin', 'netout'], +- fieldTitles: [gettext('Incoming'), gettext('Outgoing')], +- store: rrdstore, +- }, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('CPU Pressure Stall'), +- fieldTitles: ['Some'], +- fields: ['pressurecpusome'], +- colors: ['#FFD13E', '#A61120'], +- store: rrdstore, +- unit: 'percent', +- }, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('IO Pressure Stall'), +- fieldTitles: ['Some', 'Full'], +- fields: ['pressureiosome', 'pressureiofull'], +- colors: ['#FFD13E', '#A61120'], +- store: rrdstore, +- unit: 'percent', +- }, +- { +- xtype: 'proxmoxRRDChart', +- title: gettext('Memory Pressure Stall'), +- fieldTitles: ['Some', 'Full'], +- fields: ['pressurememorysome', 'pressurememoryfull'], +- colors: ['#FFD13E', '#A61120'], +- store: rrdstore, +- unit: 'percent', +- }, +- ], +- listeners: { +- resize: function (panel) { +- Proxmox.Utils.updateColumns(panel); +- }, +- }, +- }, +- ], +- listeners: { +- activate: function () { +- rstore.setInterval(1000); +- rstore.startUpdate(); // just to be sure +- rrdstore.startUpdate(); +- }, +- destroy: function () { +- rstore.setInterval(5000); // don't stop it, it's not ours! +- rrdstore.stopUpdate(); +- }, +- }, +- }); +- +- me.updateRepositoryStatus(); +- +- me.callParent(); +- +- let sp = Ext.state.Manager.getProvider(); +- me.mon(sp, 'statechange', function (provider, key, value) { +- if (key !== 'summarycolumns') { +- return; +- } +- Proxmox.Utils.updateColumns(me.getComponent('itemcontainer')); +- }); +- }, +-}); ++// Ext.define('PVE.node.Summary', { ++// extend: 'Ext.panel.Panel', ++// alias: 'widget.pveNodeSummary', ++// ++// scrollable: true, ++// bodyPadding: 5, ++// ++// showVersions: function () { ++// var me = this; ++// ++// // Note: we use simply text/html here, because ExtJS grid has problems ++// // with cut&paste ++// ++// var nodename = me.pveSelNode.data.node; ++// ++// var view = Ext.createWidget('component', { ++// autoScroll: true, ++// id: 'pkgversions', ++// padding: 5, ++// style: { ++// 'white-space': 'pre', ++// 'font-family': 'monospace', ++// }, ++// }); ++// ++// var win = Ext.create('Ext.window.Window', { ++// title: gettext('Package versions'), ++// width: 600, ++// height: 600, ++// layout: 'fit', ++// modal: true, ++// items: [view], ++// buttons: [ ++// { ++// xtype: 'button', ++// iconCls: 'fa fa-clipboard', ++// handler: function (button) { ++// window ++// .getSelection() ++// .selectAllChildren(document.getElementById('pkgversions')); ++// document.execCommand('copy'); ++// }, ++// text: gettext('Copy'), ++// }, ++// { ++// text: gettext('Ok'), ++// handler: function () { ++// this.up('window').close(); ++// }, ++// }, ++// ], ++// }); ++// ++// Proxmox.Utils.API2Request({ ++// waitMsgTarget: me, ++// url: `/nodes/${nodename}/apt/versions`, ++// method: 'GET', ++// failure: function (response, opts) { ++// win.close(); ++// Ext.Msg.alert(gettext('Error'), response.htmlStatus); ++// }, ++// success: function (response, opts) { ++// win.show(); ++// let text = ''; ++// Ext.Array.each(response.result.data, function (rec) { ++// let version = 'not correctly installed'; ++// let pkg = rec.Package; ++// if (rec.OldVersion && rec.CurrentState === 'Installed') { ++// version = rec.OldVersion; ++// } ++// if (rec.RunningKernel) { ++// text += `${pkg}: ${version} (running kernel: ${rec.RunningKernel})\n`; ++// } else if (rec.ManagerVersion) { ++// text += `${pkg}: ${version} (running version: ${rec.ManagerVersion})\n`; ++// } else { ++// text += `${pkg}: ${version}\n`; ++// } ++// }); ++// ++// view.update(Ext.htmlEncode(text)); ++// }, ++// }); ++// }, ++// ++// updateRepositoryStatus: function () { ++// let me = this; ++// let repoStatus = me.nodeStatus.down('#repositoryStatus'); ++// ++// let nodename = me.pveSelNode.data.node; ++// ++// Proxmox.Utils.API2Request({ ++// url: `/nodes/${nodename}/apt/repositories`, ++// method: 'GET', ++// failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus), ++// success: (response) => ++// repoStatus.setRepositoryInfo(response.result.data['standard-repos']), ++// }); ++// ++// Proxmox.Utils.API2Request({ ++// url: `/nodes/${nodename}/subscription`, ++// method: 'GET', ++// failure: (response) => Ext.Msg.alert(gettext('Error'), response.htmlStatus), ++// success: function (response, opts) { ++// const res = response.result; ++// const subscription = res?.data?.status.toLowerCase() === 'active'; ++// repoStatus.setSubscriptionStatus(subscription); ++// }, ++// }); ++// }, ++// ++// initComponent: function () { ++// var me = this; ++// ++// var nodename = me.pveSelNode.data.node; ++// if (!nodename) { ++// throw 'no node name specified'; ++// } ++// ++// if (!me.statusStore) { ++// throw 'no status storage specified'; ++// } ++// ++// var rstore = me.statusStore; ++// ++// var version_btn = new Ext.Button({ ++// text: gettext('Package versions'), ++// handler: function () { ++// Proxmox.Utils.checked_command(function () { ++// me.showVersions(); ++// }); ++// }, ++// }); ++// ++// var rrdstore = Ext.create('Proxmox.data.RRDStore', { ++// rrdurl: '/api2/json/nodes/' + nodename + '/rrddata', ++// 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', ++// itemId: 'itemcontainer', ++// layout: 'column', ++// minWidth: 700, ++// defaults: { ++// minHeight: 360, ++// padding: 5, ++// columnWidth: 1, ++// }, ++// items: [ ++// nodeStatus, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('CPU Usage'), ++// fields: ['cpu', 'iowait'], ++// fieldTitles: [gettext('CPU usage'), gettext('IO delay')], ++// unit: 'percent', ++// store: rrdstore, ++// }, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('Server Load'), ++// fields: ['loadavg'], ++// fieldTitles: [gettext('Load average')], ++// store: rrdstore, ++// }, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('Memory usage'), ++// fields: [ ++// { ++// yField: 'memtotal', ++// title: gettext('Total'), ++// tooltip: { ++// trackMouse: true, ++// renderer: function (toolTip, record, item) { ++// let value = record.get('memtotal'); ++// ++// if (value === null) { ++// toolTip.setHtml(gettext('No Data')); ++// } else { ++// let total = Proxmox.Utils.format_size(value); ++// let time = new Date(record.get('time')); ++// ++// let avail = record.get('memavailable'); ++// let availText = ''; ++// if (Ext.isNumeric(avail)) { ++// let v = Proxmox.Utils.format_size(avail); ++// availText = ` (${gettext('Available')}: ${v})`; ++// } ++// ++// toolTip.setHtml( ++// `${gettext('Total')}: ${total}${availText}
${time}`, ++// ); ++// } ++// }, ++// }, ++// }, ++// { ++// yField: 'memused', ++// title: gettext('Used'), ++// tooltip: { ++// trackMouse: true, ++// renderer: function (toolTip, record, item) { ++// let value = record.get('memused'); ++// ++// if (value === null) { ++// toolTip.setHtml(gettext('No Data')); ++// } else { ++// let total = Proxmox.Utils.format_size(value); ++// let time = new Date(record.get('time')); ++// ++// let arc = record.get('arcsize'); ++// let arcText = ''; ++// if (Ext.isNumeric(arc) && arc > 1024 * 1024) { ++// let v = Proxmox.Utils.format_size(value - arc); ++// arcText = ` (${gettext('Without ZFS ARC')}: ${v})`; ++// } ++// ++// toolTip.setHtml( ++// `${gettext('Used')}: ${total}${arcText}
${time}`, ++// ); ++// } ++// }, ++// }, ++// }, ++// 'arcsize', ++// { ++// type: 'line', ++// fill: false, ++// yField: 'memavailable', ++// title: gettext('Available'), ++// style: { ++// lineWidth: 2.5, ++// opacity: 1, ++// }, ++// }, ++// ], ++// fieldTitles: [ ++// gettext('Total'), ++// gettext('Used'), ++// gettext('ZFS ARC'), ++// gettext('Available'), ++// ], ++// colors: ['#94ae0a', '#115fa6', '#24AD9A', '#bbde0d'], ++// unit: 'bytes', ++// powerOfTwo: true, ++// store: rrdstore, ++// }, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('Network Traffic'), ++// fields: ['netin', 'netout'], ++// fieldTitles: [gettext('Incoming'), gettext('Outgoing')], ++// store: rrdstore, ++// }, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('CPU Pressure Stall'), ++// fieldTitles: ['Some'], ++// fields: ['pressurecpusome'], ++// colors: ['#FFD13E', '#A61120'], ++// store: rrdstore, ++// unit: 'percent', ++// }, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('IO Pressure Stall'), ++// fieldTitles: ['Some', 'Full'], ++// fields: ['pressureiosome', 'pressureiofull'], ++// colors: ['#FFD13E', '#A61120'], ++// store: rrdstore, ++// unit: 'percent', ++// }, ++// { ++// xtype: 'proxmoxRRDChart', ++// title: gettext('Memory Pressure Stall'), ++// fieldTitles: ['Some', 'Full'], ++// fields: ['pressurememorysome', 'pressurememoryfull'], ++// colors: ['#FFD13E', '#A61120'], ++// store: rrdstore, ++// unit: 'percent', ++// }, ++// ], ++// listeners: { ++// resize: function (panel) { ++// Proxmox.Utils.updateColumns(panel); ++// }, ++// }, ++// }, ++// ], ++// listeners: { ++// activate: function () { ++// rstore.setInterval(1000); ++// rstore.startUpdate(); // just to be sure ++// rrdstore.startUpdate(); ++// }, ++// destroy: function () { ++// rstore.setInterval(5000); // don't stop it, it's not ours! ++// rrdstore.stopUpdate(); ++// }, ++// }, ++// }); ++// ++// me.updateRepositoryStatus(); ++// ++// me.callParent(); ++// ++// let sp = Ext.state.Manager.getProvider(); ++// me.mon(sp, 'statechange', function (provider, key, value) { ++// if (key !== 'summarycolumns') { ++// return; ++// } ++// Proxmox.Utils.updateColumns(me.getComponent('itemcontainer')); ++// }); ++// }, ++// }); + Ext.define('PVE.node.CreateZFS', { + extend: 'Proxmox.window.Edit', + xtype: 'pveCreateZFS',