]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/lxc/Resources.js
ui: mpedit: activate backup on MP creation
[pve-manager.git] / www / manager6 / lxc / Resources.js
1 /*jslint confusion: true */
2 Ext.define('PVE.lxc.RessourceView', {
3 extend: 'Proxmox.grid.PendingObjectGrid',
4 alias: ['widget.pveLxcRessourceView'],
5
6 onlineHelp: 'pct_configuration',
7
8 renderKey: function(key, metaData, rec, rowIndex, colIndex, store) {
9 var me = this;
10 var rowdef = me.rows[key] || {};
11
12 metaData.tdAttr = "valign=middle";
13 if (rowdef.tdCls) {
14 metaData.tdCls = rowdef.tdCls;
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');
34 var diskCap = caps.vms['VM.Config.Disk'];
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,
42 defaultValue: 512,
43 tdCls: 'pve-itype-icon-memory',
44 group: 1,
45 renderer: function(value) {
46 return Proxmox.Utils.format_size(value*1024*1024);
47 }
48 },
49 swap: {
50 header: gettext('Swap'),
51 editor: caps.vms['VM.Config.Memory'] ? 'PVE.lxc.MemoryEdit' : undefined,
52 defaultValue: 512,
53 tdCls: 'pve-itype-icon-swap',
54 group: 2,
55 renderer: function(value) {
56 return Proxmox.Utils.format_size(value*1024*1024);
57 }
58 },
59 cores: {
60 header: gettext('Cores'),
61 editor: caps.vms['VM.Config.CPU'] ? 'PVE.lxc.CPUEdit' : undefined,
62 defaultValue: '',
63 tdCls: 'pve-itype-icon-processor',
64 group: 3,
65 renderer: function(value) {
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;
83 }
84 },
85 rootfs: {
86 header: gettext('Root Disk'),
87 defaultValue: Proxmox.Utils.noneText,
88 editor: mpeditor,
89 tdCls: 'pve-itype-icon-storage',
90 group: 4
91 },
92 cpulimit: {
93 visible: false
94 },
95 cpuunits: {
96 visible: false
97 },
98 unprivileged: {
99 visible: false
100 }
101 };
102
103 PVE.Utils.forEachMP(function(bus, i) {
104 confid = bus + i;
105 var group = 5;
106 var header;
107 if (bus === 'mp') {
108 header = gettext('Mount Point') + ' (' + confid + ')';
109 } else {
110 header = gettext('Unused Disk') + ' ' + i;
111 group += 1;
112 }
113 rows[confid] = {
114 group: group,
115 order: i,
116 tdCls: 'pve-itype-icon-storage',
117 editor: mpeditor,
118 header: header
119 };
120 }, true);
121
122 var baseurl = 'nodes/' + nodename + '/lxc/' + vmid + '/config';
123
124 me.selModel = Ext.create('Ext.selection.RowModel', {});
125
126 var run_resize = function() {
127 var rec = me.selModel.getSelection()[0];
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();
139 };
140
141 var run_remove = function(b, e, rec) {
142 Proxmox.Utils.API2Request({
143 url: '/api2/extjs/' + baseurl,
144 waitMsgTarget: me,
145 method: 'PUT',
146 params: {
147 'delete': rec.data.key
148 },
149 failure: function (response, opts) {
150 Ext.Msg.alert('Error', response.htmlStatus);
151 }
152 });
153 };
154
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
172 var edit_btn = new Proxmox.button.Button({
173 text: gettext('Edit'),
174 selModel: me.selModel,
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 },
183 handler: function() { me.run_editor(); }
184 });
185
186 var resize_btn = new Proxmox.button.Button({
187 text: gettext('Resize disk'),
188 selModel: me.selModel,
189 disabled: true,
190 handler: run_resize
191 });
192
193 var remove_btn = new Proxmox.button.Button({
194 text: gettext('Remove'),
195 selModel: me.selModel,
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+$/)) {
202 msg += " " + gettext('This will permanently erase all data.');
203 }
204
205 return msg;
206 },
207 handler: run_remove
208 });
209
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
218 var revert_btn = new PVE.button.PendingRevert();
219
220 var set_button_status = function() {
221 var rec = me.selModel.getSelection()[0];
222
223 if (!rec) {
224 edit_btn.disable();
225 remove_btn.disable();
226 resize_btn.disable();
227 revert_btn.disable();
228 return;
229 }
230 var key = rec.data.key;
231 var value = rec.data.value;
232 var rowdef = rows[key];
233
234 var pending = rec.data['delete'] || me.hasPendingChanges(key);
235 var isDisk = (rowdef.tdCls == 'pve-itype-icon-storage');
236 var isUnusedDisk = key.match(/^unused\d+/);
237
238 var noedit = rec.data['delete'] || !rowdef.editor;
239 if (!noedit && Proxmox.UserName !== 'root@pam' && key.match(/^mp\d+$/)) {
240 var mp = PVE.Parser.parseLxcMountPoint(value);
241 if (mp.type !== 'volume') {
242 noedit = true;
243 }
244 }
245 edit_btn.setDisabled(noedit);
246
247 remove_btn.setDisabled(!isDisk || rec.data.key === 'rootfs' || !diskCap || pending);
248 resize_btn.setDisabled(!isDisk || !diskCap || isUnusedDisk);
249 move_btn.setDisabled(!isDisk || !diskCap);
250 revert_btn.setDisabled(!pending);
251
252 };
253
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 }
277 };
278
279 Ext.apply(me, {
280 url: "/api2/json/nodes/" + nodename + "/lxc/" + vmid + "/pending",
281 selModel: me.selModel,
282 interval: 2000,
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,
296 unprivileged: me.getObjectValue('unprivileged'),
297 pveSelNode: me.pveSelNode
298 });
299 win.on('destroy', me.reload, me);
300 win.show();
301 }
302 }
303 ]
304 })
305 },
306 edit_btn,
307 remove_btn,
308 resize_btn,
309 move_btn,
310 revert_btn
311 ],
312 rows: rows,
313 sorterFn: sorterFn,
314 editorConfig: {
315 pveSelNode: me.pveSelNode,
316 url: '/api2/extjs/' + baseurl
317 },
318 listeners: {
319 itemdblclick: me.run_editor,
320 selectionchange: set_button_status
321 }
322 });
323
324 me.callParent();
325
326 me.on('activate', me.rstore.startUpdate);
327 me.on('destroy', me.rstore.stopUpdate);
328 me.on('deactivate', me.rstore.stopUpdate);
329
330 me.mon(me.getStore(), 'datachanged', function() {
331 set_button_status();
332 });
333
334 Ext.apply(me.editorConfig, { unprivileged: me.getObjectValue('unprivileged') });
335 }
336 });