]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/lxc/Resources.js
1 Ext
.define('PVE.lxc.RessourceView', {
2 extend
: 'Proxmox.grid.PendingObjectGrid',
3 alias
: ['widget.pveLxcRessourceView'],
5 onlineHelp
: 'pct_configuration',
7 renderKey: function(key
, metaData
, rec
, rowIndex
, colIndex
, store
) {
9 let rowdef
= me
.rows
[key
] || {};
11 let txt
= rowdef
.header
|| key
;
14 metaData
.tdAttr
= "valign=middle";
16 metaData
.tdCls
= rowdef
.tdCls
;
17 } else if (rowdef
.iconCls
) {
18 icon
= `<i class='pve-grid-fa fa fa-fw fa-${rowdef.iconCls}'></i>`;
19 metaData
.tdCls
+= " pve-itype-fa";
21 // only return icons in grid but not remove dialog
22 if (rowIndex
!== undefined) {
29 initComponent: function() {
33 var nodename
= me
.pveSelNode
.data
.node
;
35 throw "no node name specified";
38 var vmid
= me
.pveSelNode
.data
.vmid
;
40 throw "no VM ID specified";
43 var caps
= Ext
.state
.Manager
.get('GuiCap');
44 var diskCap
= caps
.vms
['VM.Config.Disk'];
46 var mpeditor
= caps
.vms
['VM.Config.Disk'] ? 'PVE.lxc.MountPointEdit' : undefined;
50 header
: gettext('Memory'),
51 editor
: caps
.vms
['VM.Config.Memory'] ? 'PVE.lxc.MemoryEdit' : undefined,
53 tdCls
: 'pmx-itype-icon-memory',
55 renderer: function(value
) {
56 return Proxmox
.Utils
.format_size(value
*1024*1024);
60 header
: gettext('Swap'),
61 editor
: caps
.vms
['VM.Config.Memory'] ? 'PVE.lxc.MemoryEdit' : undefined,
65 renderer: function(value
) {
66 return Proxmox
.Utils
.format_size(value
*1024*1024);
70 header
: gettext('Cores'),
71 editor
: caps
.vms
['VM.Config.CPU'] ? 'PVE.lxc.CPUEdit' : undefined,
73 tdCls
: 'pmx-itype-icon-processor',
75 renderer: function(value
) {
76 var cpulimit
= me
.getObjectValue('cpulimit');
77 var cpuunits
= me
.getObjectValue('cpuunits');
82 res
= gettext('unlimited');
86 res
+= ' [cpulimit=' + cpulimit
+ ']';
90 res
+= ' [cpuunits=' + cpuunits
+ ']';
96 header
: gettext('Root Disk'),
97 defaultValue
: Proxmox
.Utils
.noneText
,
113 PVE
.Utils
.forEachMP(function(bus
, i
) {
118 header
= gettext('Mount Point') + ' (' + confid
+ ')';
120 header
= gettext('Unused Disk') + ' ' + i
;
126 tdCls
: 'pve-itype-icon-storage',
132 var baseurl
= 'nodes/' + nodename
+ '/lxc/' + vmid
+ '/config';
134 me
.selModel
= Ext
.create('Ext.selection.RowModel', {});
136 var run_resize = function() {
137 var rec
= me
.selModel
.getSelection()[0];
142 var win
= Ext
.create('PVE.window.MPResize', {
151 var run_remove = function(b
, e
, rec
) {
152 Proxmox
.Utils
.API2Request({
153 url
: '/api2/extjs/' + baseurl
,
157 'delete': rec
.data
.key
,
159 failure: function(response
, opts
) {
160 Ext
.Msg
.alert('Error', response
.htmlStatus
);
165 var run_move = function(b
, e
, rec
) {
170 var win
= Ext
.create('PVE.window.HDMove', {
179 win
.on('destroy', me
.reload
, me
);
182 var edit_btn
= new Proxmox
.button
.Button({
183 text
: gettext('Edit'),
184 selModel
: me
.selModel
,
186 enableFn: function(rec
) {
190 var rowdef
= rows
[rec
.data
.key
];
191 return !!rowdef
.editor
;
193 handler: function() { me
.run_editor(); },
196 var resize_btn
= new Proxmox
.button
.Button({
197 text
: gettext('Resize disk'),
198 selModel
: me
.selModel
,
203 var remove_btn
= new Proxmox
.button
.Button({
204 text
: gettext('Remove'),
205 defaultText
: gettext('Remove'),
206 altText
: gettext('Detach'),
207 selModel
: me
.selModel
,
210 confirmMsg: function(rec
) {
211 let warn
= Ext
.String
.format(gettext('Are you sure you want to remove entry {0}'));
212 if (this.text
=== this.altText
) {
213 warn
= gettext('Are you sure you want to detach entry {0}');
215 let rendered
= me
.renderKey(rec
.data
.key
, {}, rec
);
216 let msg
= Ext
.String
.format(warn
, `'${rendered}'`);
218 if (rec
.data
.key
.match(/^unused\d+$/)) {
219 msg
+= " " + gettext('This will permanently erase all data.');
225 render: function(btn
) {
226 // hack: calculate the max button width on first display to prevent the whole
227 // toolbar to move when we switch between the "Remove" and "Detach" labels
228 let def
= btn
.getSize().width
;
230 btn
.setText(btn
.altText
);
231 let alt
= btn
.getSize().width
;
233 btn
.setText(btn
.defaultText
);
235 let optimal
= alt
> def
? alt
: def
;
236 btn
.setSize({ width
: optimal
});
241 var move_btn
= new Proxmox
.button
.Button({
242 text
: gettext('Move Volume'),
243 selModel
: me
.selModel
,
249 var revert_btn
= new PVE
.button
.PendingRevert();
251 var set_button_status = function() {
252 var rec
= me
.selModel
.getSelection()[0];
256 remove_btn
.disable();
257 resize_btn
.disable();
258 revert_btn
.disable();
261 var key
= rec
.data
.key
;
262 var value
= rec
.data
.value
;
263 var rowdef
= rows
[key
];
265 var pending
= rec
.data
.delete || me
.hasPendingChanges(key
);
266 let isDisk
= key
=== 'rootfs' || key
.match(/^(mp|unused)\d+/);
267 var isUnusedDisk
= key
.match(/^unused\d+/);
268 var isUsedDisk
= isDisk
&& !isUnusedDisk
;
270 var noedit
= rec
.data
.delete || !rowdef
.editor
;
271 if (!noedit
&& Proxmox
.UserName
!== 'root@pam' && key
.match(/^mp\d+$/)) {
272 var mp
= PVE
.Parser
.parseLxcMountPoint(value
);
273 if (mp
.type
!== 'volume') {
277 edit_btn
.setDisabled(noedit
);
279 remove_btn
.setDisabled(!isDisk
|| rec
.data
.key
=== 'rootfs' || !diskCap
|| pending
);
280 resize_btn
.setDisabled(!isDisk
|| !diskCap
|| isUnusedDisk
);
281 move_btn
.setDisabled(!isDisk
|| !diskCap
);
282 revert_btn
.setDisabled(!pending
);
284 remove_btn
.setText(isUsedDisk
? remove_btn
.altText
: remove_btn
.defaultText
);
287 var sorterFn = function(rec1
, rec2
) {
288 var v1
= rec1
.data
.key
;
289 var v2
= rec2
.data
.key
;
290 var g1
= rows
[v1
].group
|| 0;
291 var g2
= rows
[v2
].group
|| 0;
292 var order1
= rows
[v1
].order
|| 0;
293 var order2
= rows
[v2
].order
|| 0;
299 if (order1
- order2
!== 0) {
300 return order1
- order2
;
305 } else if (v1
< v2
) {
313 url
: "/api2/json/nodes/" + nodename
+ "/lxc/" + vmid
+ "/pending",
314 selModel
: me
.selModel
,
319 text
: gettext('Add'),
320 menu
: new Ext
.menu
.Menu({
323 text
: gettext('Mount Point'),
324 iconCls
: 'fa fa-fw fa-hdd-o black',
325 disabled
: !caps
.vms
['VM.Config.Disk'],
326 handler: function() {
327 Ext
.create('PVE.lxc.MountPointEdit', {
329 url
: `/api2/extjs/${baseurl}`,
330 unprivileged
: me
.getObjectValue('unprivileged'),
331 pveSelNode
: me
.pveSelNode
,
333 destroy
: () => me
.reload(),
350 pveSelNode
: me
.pveSelNode
,
351 url
: '/api2/extjs/' + baseurl
,
354 itemdblclick
: me
.run_editor
,
355 selectionchange
: set_button_status
,
361 me
.on('activate', me
.rstore
.startUpdate
);
362 me
.on('destroy', me
.rstore
.stopUpdate
);
363 me
.on('deactivate', me
.rstore
.stopUpdate
);
365 me
.mon(me
.getStore(), 'datachanged', function() {
369 Ext
.apply(me
.editorConfig
, { unprivileged
: me
.getObjectValue('unprivileged') });