]> git.proxmox.com Git - proxmox-backup.git/blob - www/datastore/Summary.js
ui: add all online help refs found in docs
[proxmox-backup.git] / www / datastore / Summary.js
1 Ext.define('pve-rrd-datastore', {
2 extend: 'Ext.data.Model',
3 fields: [
4 'used',
5 'total',
6 'read_ios',
7 'read_bytes',
8 'write_ios',
9 'write_bytes',
10 'io_ticks',
11 {
12 name: 'io_delay', calculate: function(data) {
13 let ios = 0;
14 if (data.read_ios !== undefined) { ios += data.read_ios; }
15 if (data.write_ios !== undefined) { ios += data.write_ios; }
16 if (data.io_ticks === undefined) {
17 return undefined;
18 } else if (ios === 0) {
19 return 0;
20 }
21 return (data.io_ticks*1000.0)/ios;
22 },
23 },
24 { type: 'date', dateFormat: 'timestamp', name: 'time' },
25 ],
26 });
27
28 Ext.define('PBS.DataStoreInfo', {
29 extend: 'Ext.panel.Panel',
30 alias: 'widget.pbsDataStoreInfo',
31
32 viewModel: {
33 data: {
34 countstext: '',
35 usage: {},
36 stillbad: 0,
37 removedbytes: 0,
38 mountpoint: "",
39 },
40 },
41
42 controller: {
43 xclass: 'Ext.app.ViewController',
44
45 onLoad: function(store, data, success) {
46 if (!success) return;
47 let me = this;
48 let vm = me.getViewModel();
49
50 let counts = store.getById('counts').data.value;
51 let total = store.getById('total').data.value;
52 let used = store.getById('used').data.value;
53
54 let usage = PBS.Utils.render_size_usage(used, total);
55 vm.set('usagetext', usage);
56 vm.set('usage', used/total);
57
58 let gcstatus = store.getById('gc-status').data.value;
59
60 let dedup = PBS.Utils.calculate_dedup_factor(gcstatus);
61
62 let countstext = function(count) {
63 count = count || {};
64 return `${count.groups || 0} ${gettext('Groups')}, ${count.snapshots || 0} ${gettext('Snapshots')}`;
65 };
66
67 vm.set('ctcount', countstext(counts.ct));
68 vm.set('vmcount', countstext(counts.vm));
69 vm.set('hostcount', countstext(counts.host));
70 vm.set('deduplication', dedup.toFixed(2));
71 vm.set('stillbad', gcstatus['still-bad']);
72 vm.set('removedbytes', Proxmox.Utils.format_size(gcstatus['removed-bytes']));
73 },
74
75 startStore: function() { this.store.startUpdate(); },
76 stopStore: function() { this.store.stopUpdate(); },
77
78 init: function(view) {
79 let me = this;
80 let datastore = encodeURIComponent(view.datastore);
81 me.store = Ext.create('Proxmox.data.ObjectStore', {
82 interval: 5*1000,
83 url: `/api2/json/admin/datastore/${datastore}/status`,
84 });
85 me.store.on('load', me.onLoad, me);
86 },
87 },
88
89 listeners: {
90 activate: 'startStore',
91 destroy: 'stopStore',
92 deactivate: 'stopStore',
93 },
94
95 defaults: {
96 xtype: 'pmxInfoWidget',
97 },
98
99 bodyPadding: 20,
100
101 items: [
102 {
103 iconCls: 'fa fa-fw fa-hdd-o',
104 title: gettext('Usage'),
105 bind: {
106 data: {
107 usage: '{usage}',
108 text: '{usagetext}',
109 },
110 },
111 },
112 {
113 xtype: 'box',
114 html: `<b>${gettext('Backup Count')}</b>`,
115 padding: '10 0 5 0',
116 },
117 {
118 iconCls: 'fa fa-fw fa-cube',
119 title: gettext('CT'),
120 printBar: false,
121 bind: {
122 data: {
123 text: '{ctcount}',
124 },
125 },
126 },
127 {
128 iconCls: 'fa fa-fw fa-building',
129 title: gettext('Host'),
130 printBar: false,
131 bind: {
132 data: {
133 text: '{hostcount}',
134 },
135 },
136 },
137 {
138 iconCls: 'fa fa-fw fa-desktop',
139 title: gettext('VM'),
140 printBar: false,
141 bind: {
142 data: {
143 text: '{vmcount}',
144 },
145 },
146 },
147 {
148 xtype: 'box',
149 html: `<b>${gettext('Stats from last Garbage Collection')}</b>`,
150 padding: '10 0 5 0',
151 },
152 {
153 iconCls: 'fa fa-fw fa-compress',
154 title: gettext('Deduplication Factor'),
155 printBar: false,
156 bind: {
157 data: {
158 text: '{deduplication}',
159 },
160 },
161 },
162 {
163 iconCls: 'fa fa-fw fa-trash-o',
164 title: gettext('Removed Bytes'),
165 printBar: false,
166 bind: {
167 data: {
168 text: '{removedbytes}',
169 },
170 },
171 },
172 {
173 iconCls: 'fa critical fa-fw fa-exclamation-triangle',
174 title: gettext('Bad Chunks'),
175 printBar: false,
176 bind: {
177 data: {
178 text: '{stillbad}',
179 },
180 visible: '{stillbad}',
181 },
182 },
183 ],
184 });
185
186 Ext.define('PBS.DataStoreSummary', {
187 extend: 'Ext.panel.Panel',
188 alias: 'widget.pbsDataStoreSummary',
189 mixins: ['Proxmox.Mixin.CBind'],
190
191 layout: 'column',
192 scrollable: true,
193
194 bodyPadding: 5,
195 defaults: {
196 columnWidth: 1,
197 padding: 5,
198 },
199
200 tbar: ['->', { xtype: 'proxmoxRRDTypeSelector' }],
201
202 items: [
203 {
204 xtype: 'container',
205 height: 300,
206 layout: {
207 type: 'hbox',
208 align: 'stretch',
209 },
210 items: [
211 {
212 xtype: 'pbsDataStoreInfo',
213 flex: 1,
214 padding: '0 10 0 0',
215 cbind: {
216 title: '{datastore}',
217 datastore: '{datastore}',
218 },
219 },
220 {
221 xtype: 'pbsDataStoreNotes',
222 flex: 1,
223 cbind: {
224 datastore: '{datastore}',
225 },
226 },
227 ],
228 },
229 {
230 xtype: 'proxmoxRRDChart',
231 title: gettext('Storage usage (bytes)'),
232 fields: ['total', 'used'],
233 fieldTitles: [gettext('Total'), gettext('Storage usage')],
234 },
235 {
236 xtype: 'proxmoxRRDChart',
237 title: gettext('Transfer Rate (bytes/second)'),
238 fields: ['read_bytes', 'write_bytes'],
239 fieldTitles: [gettext('Read'), gettext('Write')],
240 },
241 {
242 xtype: 'proxmoxRRDChart',
243 title: gettext('Input/Output Operations per Second (IOPS)'),
244 fields: ['read_ios', 'write_ios'],
245 fieldTitles: [gettext('Read'), gettext('Write')],
246 },
247 {
248 xtype: 'proxmoxRRDChart',
249 title: gettext('IO Delay (ms)'),
250 fields: ['io_delay'],
251 fieldTitles: [gettext('IO Delay')],
252 },
253 ],
254
255 listeners: {
256 activate: function() { this.rrdstore.startUpdate(); },
257 deactivate: function() { this.rrdstore.stopUpdate(); },
258 destroy: function() { this.rrdstore.stopUpdate(); },
259 },
260
261 initComponent: function() {
262 let me = this;
263
264 me.rrdstore = Ext.create('Proxmox.data.RRDStore', {
265 rrdurl: "/api2/json/admin/datastore/" + me.datastore + "/rrd",
266 model: 'pve-rrd-datastore',
267 });
268
269 me.callParent();
270
271 Proxmox.Utils.API2Request({
272 url: `/config/datastore/${me.datastore}`,
273 waitMsgTarget: me.down('pbsDataStoreInfo'),
274 success: function(response) {
275 let path = Ext.htmlEncode(response.result.data.path);
276 me.down('pbsDataStoreInfo').setTitle(`${me.datastore} (${path})`);
277 me.down('pbsDataStoreNotes').setNotes(response.result.data.comment);
278 },
279 });
280
281 me.query('proxmoxRRDChart').forEach((chart) => {
282 chart.setStore(me.rrdstore);
283 });
284
285 me.down('pbsDataStoreInfo').relayEvents(me, ['activate', 'deactivate']);
286 },
287 });