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