]> git.proxmox.com Git - pve-manager.git/blame - www/manager6/lxc/Resources.js
ui/vnc: reload IFrame-embedded xtermjs on LXC startup
[pve-manager.git] / www / manager6 / lxc / Resources.js
CommitLineData
c7ee0c11
DM
1/*jslint confusion: true */
2Ext.define('PVE.lxc.RessourceView', {
9fd8d73e 3 extend: 'Proxmox.grid.PendingObjectGrid',
c7ee0c11
DM
4 alias: ['widget.pveLxcRessourceView'],
5
ba93a9c6
DC
6 onlineHelp: 'pct_configuration',
7
c7ee0c11
DM
8 renderKey: function(key, metaData, rec, rowIndex, colIndex, store) {
9 var me = this;
14dd743b 10 var rowdef = me.rows[key] || {};
c7ee0c11
DM
11
12 metaData.tdAttr = "valign=middle";
c7ee0c11
DM
13 if (rowdef.tdCls) {
14 metaData.tdCls = rowdef.tdCls;
c7ee0c11
DM
15 }
16 return rowdef.header || key;
17 },
18
19 initComponent : function() {
20 var me = this;
21 var i, confid;
22
23 var nodename = me.pveSelNode.data.node;
24 if (!nodename) {
25 throw "no node name specified";
26 }
27
28 var vmid = me.pveSelNode.data.vmid;
29 if (!vmid) {
30 throw "no VM ID specified";
31 }
32
33 var caps = Ext.state.Manager.get('GuiCap');
d35b5b2a 34 var diskCap = caps.vms['VM.Config.Disk'];
c7ee0c11
DM
35
36 var mpeditor = caps.vms['VM.Config.Disk'] ? 'PVE.lxc.MountPointEdit' : undefined;
37
38 var rows = {
39 memory: {
40 header: gettext('Memory'),
41 editor: caps.vms['VM.Config.Memory'] ? 'PVE.lxc.MemoryEdit' : undefined,
c7ee0c11
DM
42 defaultValue: 512,
43 tdCls: 'pve-itype-icon-memory',
1a2fdf62 44 group: 1,
c7ee0c11 45 renderer: function(value) {
e7ade592 46 return Proxmox.Utils.format_size(value*1024*1024);
c7ee0c11
DM
47 }
48 },
49 swap: {
50 header: gettext('Swap'),
51 editor: caps.vms['VM.Config.Memory'] ? 'PVE.lxc.MemoryEdit' : undefined,
c7ee0c11
DM
52 defaultValue: 512,
53 tdCls: 'pve-itype-icon-swap',
1a2fdf62 54 group: 2,
c7ee0c11 55 renderer: function(value) {
e7ade592 56 return Proxmox.Utils.format_size(value*1024*1024);
c7ee0c11
DM
57 }
58 },
92b5029f
DM
59 cores: {
60 header: gettext('Cores'),
92b5029f
DM
61 editor: caps.vms['VM.Config.CPU'] ? 'PVE.lxc.CPUEdit' : undefined,
62 defaultValue: '',
63 tdCls: 'pve-itype-icon-processor',
1a2fdf62 64 group: 3,
92b5029f 65 renderer: function(value) {
3e4b78dc
DC
66 var cpulimit = me.getObjectValue('cpulimit');
67 var cpuunits = me.getObjectValue('cpuunits');
68 var res;
69 if (value) {
70 res = value;
71 } else {
72 res = gettext('unlimited');
73 }
74
75 if (cpulimit) {
76 res += ' [cpulimit=' + cpulimit + ']';
77 }
78
79 if (cpuunits) {
80 res += ' [cpuunits=' + cpuunits + ']';
81 }
82 return res;
92b5029f
DM
83 }
84 },
c7ee0c11
DM
85 rootfs: {
86 header: gettext('Root Disk'),
e7ade592 87 defaultValue: Proxmox.Utils.noneText,
c7ee0c11 88 editor: mpeditor,
1a2fdf62
DL
89 tdCls: 'pve-itype-icon-storage',
90 group: 4
c15e9cd5 91 },
3e4b78dc
DC
92 cpulimit: {
93 visible: false
94 },
95 cpuunits: {
96 visible: false
97 },
c15e9cd5
PA
98 unprivileged: {
99 visible: false
c7ee0c11
DM
100 }
101 };
102
14a845bc
DC
103 PVE.Utils.forEachMP(function(bus, i) {
104 confid = bus + i;
1a2fdf62
DL
105 var group = 5;
106 var header;
14a845bc
DC
107 if (bus === 'mp') {
108 header = gettext('Mount Point') + ' (' + confid + ')';
109 } else {
110 header = gettext('Unused Disk') + ' ' + i;
1a2fdf62 111 group += 1;
14a845bc 112 }
c7ee0c11 113 rows[confid] = {
1a2fdf62
DL
114 group: group,
115 order: i,
c7ee0c11
DM
116 tdCls: 'pve-itype-icon-storage',
117 editor: mpeditor,
14a845bc 118 header: header
c7ee0c11 119 };
14a845bc 120 }, true);
c7ee0c11 121
c7ee0c11
DM
122 var baseurl = 'nodes/' + nodename + '/lxc/' + vmid + '/config';
123
14dd743b 124 me.selModel = Ext.create('Ext.selection.RowModel', {});
c7ee0c11
DM
125
126 var run_resize = function() {
14dd743b 127 var rec = me.selModel.getSelection()[0];
c7ee0c11
DM
128 if (!rec) {
129 return;
130 }
131
132 var win = Ext.create('PVE.window.MPResize', {
133 disk: rec.data.key,
134 nodename: nodename,
135 vmid: vmid
136 });
137
138 win.show();
c7ee0c11
DM
139 };
140
141 var run_remove = function(b, e, rec) {
e7ade592 142 Proxmox.Utils.API2Request({
c7ee0c11
DM
143 url: '/api2/extjs/' + baseurl,
144 waitMsgTarget: me,
145 method: 'PUT',
146 params: {
147 'delete': rec.data.key
148 },
c7ee0c11
DM
149 failure: function (response, opts) {
150 Ext.Msg.alert('Error', response.htmlStatus);
151 }
152 });
153 };
154
c7164db7
DC
155 var run_move = function(b, e, rec) {
156 if (!rec) {
157 return;
158 }
159
160 var win = Ext.create('PVE.window.HDMove', {
161 disk: rec.data.key,
162 nodename: nodename,
163 vmid: vmid,
164 type: 'lxc'
165 });
166
167 win.show();
168
169 win.on('destroy', me.reload, me);
170 };
171
5720fafa 172 var edit_btn = new Proxmox.button.Button({
c7ee0c11 173 text: gettext('Edit'),
14dd743b 174 selModel: me.selModel,
c7ee0c11
DM
175 disabled: true,
176 enableFn: function(rec) {
177 if (!rec) {
178 return false;
179 }
180 var rowdef = rows[rec.data.key];
181 return !!rowdef.editor;
182 },
8cd96756 183 handler: function() { me.run_editor(); }
c7ee0c11
DM
184 });
185
5720fafa 186 var resize_btn = new Proxmox.button.Button({
c7ee0c11 187 text: gettext('Resize disk'),
14dd743b 188 selModel: me.selModel,
c7ee0c11
DM
189 disabled: true,
190 handler: run_resize
191 });
192
5720fafa 193 var remove_btn = new Proxmox.button.Button({
c7ee0c11 194 text: gettext('Remove'),
14dd743b 195 selModel: me.selModel,
c7ee0c11
DM
196 disabled: true,
197 dangerous: true,
198 confirmMsg: function(rec) {
199 var msg = Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
200 "'" + me.renderKey(rec.data.key, {}, rec) + "'");
201 if (rec.data.key.match(/^unused\d+$/)) {
16152937 202 msg += " " + gettext('This will permanently erase all data.');
c7ee0c11
DM
203 }
204
205 return msg;
206 },
207 handler: run_remove
208 });
209
c7164db7
DC
210 var move_btn = new Proxmox.button.Button({
211 text: gettext('Move Volume'),
212 selModel: me.selModel,
213 disabled: true,
214 dangerous: true,
215 handler: run_move
216 });
217
417f904f 218 var revert_btn = new PVE.button.PendingRevert();
273b5ce3 219
c7ee0c11 220 var set_button_status = function() {
14dd743b 221 var rec = me.selModel.getSelection()[0];
c7ee0c11
DM
222
223 if (!rec) {
224 edit_btn.disable();
225 remove_btn.disable();
226 resize_btn.disable();
273b5ce3 227 revert_btn.disable();
c7ee0c11
DM
228 return;
229 }
230 var key = rec.data.key;
231 var value = rec.data.value;
232 var rowdef = rows[key];
233
273b5ce3 234 var pending = rec.data['delete'] || me.hasPendingChanges(key);
c7ee0c11 235 var isDisk = (rowdef.tdCls == 'pve-itype-icon-storage');
5ef877b9 236 var isUnusedDisk = key.match(/^unused\d+/);
c7ee0c11
DM
237
238 var noedit = rec.data['delete'] || !rowdef.editor;
35a04562 239 if (!noedit && Proxmox.UserName !== 'root@pam' && key.match(/^mp\d+$/)) {
c7ee0c11
DM
240 var mp = PVE.Parser.parseLxcMountPoint(value);
241 if (mp.type !== 'volume') {
242 noedit = true;
243 }
244 }
245 edit_btn.setDisabled(noedit);
246
cef9b653 247 remove_btn.setDisabled(!isDisk || rec.data.key === 'rootfs' || !diskCap || pending);
5ef877b9 248 resize_btn.setDisabled(!isDisk || !diskCap || isUnusedDisk);
d35b5b2a 249 move_btn.setDisabled(!isDisk || !diskCap);
273b5ce3 250 revert_btn.setDisabled(!pending);
c7ee0c11
DM
251
252 };
253
1a2fdf62
DL
254 var sorterFn = function(rec1, rec2) {
255 var v1 = rec1.data.key;
256 var v2 = rec2.data.key;
257 var g1 = rows[v1].group || 0;
258 var g2 = rows[v2].group || 0;
259 var order1 = rows[v1].order || 0;
260 var order2 = rows[v2].order || 0;
261
262 if ((g1 - g2) !== 0) {
263 return g1 - g2;
264 }
265
266 if ((order1 - order2) !== 0) {
267 return order1 - order2;
268 }
269
270 if (v1 > v2) {
271 return 1;
272 } else if (v1 < v2) {
273 return -1;
274 } else {
275 return 0;
276 }
93bd0d75 277 };
1a2fdf62 278
f7993618 279 Ext.apply(me, {
9fd8d73e 280 url: "/api2/json/nodes/" + nodename + "/lxc/" + vmid + "/pending",
14dd743b
TL
281 selModel: me.selModel,
282 interval: 2000,
c7ee0c11
DM
283 cwidth1: 170,
284 tbar: [
285 {
286 text: gettext('Add'),
287 menu: new Ext.menu.Menu({
288 items: [
289 {
290 text: gettext('Mount Point'),
291 iconCls: 'pve-itype-icon-storage',
292 disabled: !caps.vms['VM.Config.Disk'],
293 handler: function() {
294 var win = Ext.create('PVE.lxc.MountPointEdit', {
295 url: '/api2/extjs/' + baseurl,
c15e9cd5 296 unprivileged: me.getObjectValue('unprivileged'),
c7ee0c11
DM
297 pveSelNode: me.pveSelNode
298 });
69f36699 299 win.on('destroy', me.reload, me);
c7ee0c11
DM
300 win.show();
301 }
302 }
303 ]
304 })
305 },
306 edit_btn,
307 remove_btn,
c7164db7 308 resize_btn,
273b5ce3
OB
309 move_btn,
310 revert_btn
c7ee0c11
DM
311 ],
312 rows: rows,
1a2fdf62 313 sorterFn: sorterFn,
14dd743b
TL
314 editorConfig: {
315 pveSelNode: me.pveSelNode,
316 url: '/api2/extjs/' + baseurl
317 },
c7ee0c11 318 listeners: {
14dd743b 319 itemdblclick: me.run_editor,
c7ee0c11
DM
320 selectionchange: set_button_status
321 }
322 });
323
324 me.callParent();
14dd743b
TL
325
326 me.on('activate', me.rstore.startUpdate);
327 me.on('destroy', me.rstore.stopUpdate);
328 me.on('deactivate', me.rstore.stopUpdate);
329
69f36699
DC
330 me.mon(me.getStore(), 'datachanged', function() {
331 set_button_status();
332 });
333
14dd743b 334 Ext.apply(me.editorConfig, { unprivileged: me.getObjectValue('unprivileged') });
c7ee0c11
DM
335 }
336});