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