]> git.proxmox.com Git - pmg-gui.git/blame - js/ClusterAdministration.js
quarantine action: use shadow for toast "window"
[pmg-gui.git] / js / ClusterAdministration.js
CommitLineData
ff735274 1/*global Proxmox*/
462f0688
DM
2Ext.define('pmg-cluster', {
3 extend: 'Ext.data.Model',
4 fields: [
5 'type', 'name', 'ip', 'hostrsapubkey', 'rootrsapubkey',
96a898b1
DM
6 'fingerprint', { type: 'integer', name: 'cid' },
7 { type: 'boolean', name: 'insync' },
24e6dc95 8 'memory', 'loadavg', 'uptime', 'rootfs', 'conn_error', 'level',
a6f800c4
DM
9 { type: 'number', name: 'memory_per',
10 calculate: function(data) {
11 var mem = data.memory;
12 return Ext.isObject(mem) ? mem.used/mem.total : 0;
13 }
14 },
15 { type: 'number', name: 'rootfs_per',
16 calculate: function(data) {
17 var du = data.rootfs;
18 return Ext.isObject(du) ? du.used/du.total : 0;
19 }
20 }
462f0688
DM
21 ],
22 proxy: {
23 type: 'proxmox',
b4d28dad 24 url: "/api2/json/config/cluster/status"
462f0688
DM
25 },
26 idProperty: 'cid'
27});
28
c6a1bc6b
DM
29Ext.define('PMG.ClusterJoinNodeWindow', {
30 extend: 'Proxmox.window.Edit',
31 xtype: 'pmgClusterJoinNodeWindow',
573a6e8b 32 onlineHelp: 'pmgcm_join',
c6a1bc6b
DM
33
34 title: gettext('Cluster Join'),
35
36 width: 800,
37
38 method: 'POST',
39
40 url: '/config/cluster/join',
41
42 items: [
43 {
44 xtype: 'textfield',
45 fieldLabel: 'IP Address',
46 name: 'master_ip'
47 },
48 {
49 xtype: 'textfield',
50 inputType: 'password',
51 fieldLabel: gettext('Password'),
52 name: 'password'
53 },
54 {
55 xtype: 'textfield',
56 fieldLabel: gettext('Fingerprint'),
57 name: 'fingerprint'
58 }
59 ]
60});
61
ee138d2d
DM
62Ext.define('PMG.ClusterAddNodeWindow', {
63 extend: 'Ext.window.Window',
64 xtype: 'pmgClusterAddNodeWindow',
65 mixins: ['Proxmox.Mixin.CBind'],
66
67 width: 800,
68
69 modal: true,
70
c6a1bc6b 71 title: gettext('Cluster Join') + ' : ' + gettext('Information'),
ee138d2d
DM
72
73 ipAddress: undefined,
74
75 fingerprint: undefined,
76
77 items: [
78 {
79 xtype: 'component',
80 border: false,
de0ebd99 81 padding: '10 10 10 10',
ee138d2d
DM
82 html: gettext("Please use the 'Join' button on the node you want to add, using the following IP address and fingerprint.")
83 },
84 {
85 xtype: 'container',
86 layout: 'form',
87 border: false,
88 padding: '0 10 10 10',
89 items: [
90 {
91 xtype: 'textfield',
92 fieldLabel: gettext('IP Address'),
93 cbind: { value: '{ipAddress}' },
94 editable: false
95 },
96 {
97 xtype: 'textfield',
98 fieldLabel: gettext('Fingerprint'),
99 cbind: { value: '{fingerprint}' },
100 editable: false
101 }
102 ]
103 }
104 ]
105});
106
de0ebd99
DC
107/*jslint confusion: true*/
108/* bind is a function and object */
462f0688
DM
109Ext.define('PMG.ClusterAdministration', {
110 extend: 'Ext.tab.Panel',
c77675e9 111 xtype: 'pmgClusterAdministration',
462f0688
DM
112
113 title: gettext('Cluster Administration'),
114
115 border: false,
116 defaults: { border: false },
117
c745a875
DM
118 viewModel: {
119 parent: null,
120 data: {
121 nodecount: 0,
c6a1bc6b 122 master: null
c745a875
DM
123 }
124 },
125
126 items: [
462f0688
DM
127 {
128 xtype: 'grid',
129 title: gettext('Nodes'),
130 controller: {
131 xclass: 'Ext.app.ViewController',
132
133 init: function(view) {
134 view.store.on('load', this.onLoad, this);
285cb4be 135 Proxmox.Utils.monStoreErrors(view, view.getStore(), true);
462f0688
DM
136 },
137
201f1b70 138 onLoad: function(store, records, success) {
c745a875 139 var vm = this.getViewModel();
201f1b70
DC
140 if (!success || !records) {
141 return;
142 }
c745a875 143 vm.set('nodecount', records.length);
462f0688 144
c6a1bc6b 145 var master = null;
462f0688 146 Ext.Array.each(records, function(ni) {
462f0688 147 if (ni.data.type === 'master') {
c745a875 148 master = ni;
462f0688
DM
149 }
150 });
c745a875
DM
151 vm.set('master', master);
152 },
462f0688 153
c6a1bc6b
DM
154 onCreate: function() {
155 var view = this.getView();
156
157 Proxmox.Utils.API2Request({
158 url: '/config/cluster/create',
159 method: 'POST',
160 waitMsgTarget: view,
161 failure: function (response, opts) {
162 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
163 },
164 success: function(response, options) {
165 var upid = response.result.data;
166 var win = Ext.create('Proxmox.window.TaskProgress', { upid: upid });
167 win.show();
168 win.on('destroy', function() { view.store.load(); });
169 }
170 });
171 },
172
173 onJoin: function() {
174 var view = this.getView();
175 var win = Ext.create('PMG.ClusterJoinNodeWindow', {});
176 win.show();
177 win.on('destroy', function() {
178 // fixme: logout
179 });
180 },
181
c745a875
DM
182 onAdd: function() {
183 var vm = this.getViewModel();
ee138d2d
DM
184
185 var win = Ext.create('PMG.ClusterAddNodeWindow', {
186 ipAddress: vm.get('master').get('ip'),
187 fingerprint: vm.get('master').get('fingerprint')
c745a875 188 });
ee138d2d 189
c745a875
DM
190 win.show();
191 }
462f0688
DM
192 },
193 store: {
194 autoLoad: true,
ad80b560
DM
195 model: 'pmg-cluster',
196 sorters: [ 'cid' ]
462f0688
DM
197 },
198 tbar: [
199 {
c745a875 200 text: gettext('Create'),
462f0688 201 reference: 'createButton',
c6a1bc6b 202 handler: 'onCreate',
c745a875
DM
203 bind: {
204 disabled: '{nodecount}'
205 }
206 },
207 {
208 text: gettext('Add'),
209 reference: 'addButton',
210 handler: 'onAdd',
211 bind: {
212 disabled: '{!master}'
213 }
214 },
215 {
216 text: gettext('Join'),
217 reference: 'joinButton',
c6a1bc6b 218 handler: 'onJoin',
c745a875
DM
219 bind: {
220 disabled: '{nodecount}'
221 }
462f0688
DM
222 }
223 ],
224 columns: [
225 {
226 header: gettext('Node'),
227 width: 150,
228 dataIndex: 'name'
229 },
230 {
231 header: gettext('Role'),
232 width: 100,
233 dataIndex: 'type'
234 },
235 {
236 header: gettext('ID'),
237 width: 80,
238 dataIndex: 'cid'
239 },
240 {
241
242 header: gettext('IP'),
243 width: 150,
244 dataIndex: 'ip'
245 },
96a898b1
DM
246 {
247 header: gettext('State'),
ef7b87d8 248 width: 100,
96a898b1
DM
249 renderer: function(value, metaData, record) {
250 var d = record.data;
251 var state = 'active';
c17f9fe4
DC
252 if (!d.insync) {
253 state = 'syncing';
254 }
96a898b1
DM
255 if (d.conn_error) {
256 metaData.tdCls = 'x-form-invalid-field';
257 var html = '<p>' + Ext.htmlEncode(d.conn_error) + '</p>';
258 html = html.replace(/\n/g, '<br>');
259 metaData.tdAttr = 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' +
260 html.replace(/\"/g,'&quot;') + '"';
261 state = 'error';
262 }
263 return state;
264 },
265 dataIndex: 'insync'
266 },
24e6dc95
DM
267 {
268 header: gettext('Subscription'),
269 width: 120,
270 renderer: Proxmox.Utils.format_subscription_level,
271 dataIndex: 'level'
272 },
96a898b1
DM
273 {
274 header: gettext('Uptime'),
ef7b87d8 275 width: 150,
96a898b1
DM
276 renderer: Proxmox.Utils.render_uptime,
277 dataIndex: 'uptime'
278 },
279 {
280 header: gettext('Load average'),
281 renderer: function(value) {
d7dd1562
DM
282 if (Ext.isDefined(value)) {
283 if (Ext.isArray(value)) {
284 return value[0];
285 }
286 return value.toString();
96a898b1 287 }
d7dd1562 288 return '';
96a898b1
DM
289 },
290 dataIndex: 'loadavg'
291 },
292 {
a6f800c4
DM
293 xtype: 'widgetcolumn',
294 widget: {
295 xtype: 'progressbarwidget',
296 textTpl: '{value:percent}'
96a898b1 297 },
a6f800c4
DM
298 header: gettext('RAM usage'),
299 dataIndex: 'memory_per'
96a898b1
DM
300 },
301 {
a6f800c4
DM
302 xtype: 'widgetcolumn',
303 widget: {
304 xtype: 'progressbarwidget',
305 textTpl: '{value:percent}'
96a898b1 306 },
a6f800c4
DM
307 header: gettext('HD space'),
308 dataIndex: 'rootfs_per'
96a898b1 309 }
462f0688
DM
310 ]
311 }
312 ]
313});