]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/qemu/HardwareView.js
1 // fixme: howto avoid jslint type confusion?
2 /*jslint confusion: true */
3 Ext
.define('PVE.qemu.HardwareView', {
4 extend
: 'PVE.grid.PendingObjectGrid',
5 alias
: ['widget.PVE.qemu.HardwareView'],
7 renderKey: function(key
, metaData
, rec
, rowIndex
, colIndex
, store
) {
10 var rowdef
= rows
[key
] || {};
12 metaData
.tdAttr
= "valign=middle";
15 metaData
.tdCls
= rowdef
.tdCls
;
16 if (rowdef
.tdCls
== 'pve-itype-icon-storage') {
17 var value
= me
.getObjectValue(key
, '', true);
18 if (value
.match(/media=cdrom/)) {
19 metaData
.tdCls
= 'pve-itype-icon-cdrom';
20 return rowdef
.cdheader
;
24 return rowdef
.header
|| key
;
27 initComponent : function() {
31 var nodename
= me
.pveSelNode
.data
.node
;
33 throw "no node name specified";
36 var vmid
= me
.pveSelNode
.data
.vmid
;
38 throw "no VM ID specified";
41 var caps
= Ext
.state
.Manager
.get('GuiCap');
45 header
: gettext('Memory'),
46 editor
: caps
.vms
['VM.Config.Memory'] ? 'PVE.qemu.MemoryEdit' : undefined,
49 tdCls
: 'pve-itype-icon-memory',
50 renderer: function(value
, metaData
, record
) {
51 var balloon
= me
.getObjectValue('balloon');
53 return PVE
.Utils
.format_size(balloon
*1024*1024) + "/" +
54 PVE
.Utils
.format_size(value
*1024*1024);
57 return PVE
.Utils
.format_size(value
*1024*1024);
61 header
: gettext('Processors'),
63 editor
: (caps
.vms
['VM.Config.CPU'] || caps
.vms
['VM.Config.HWType']) ?
64 'PVE.qemu.ProcessorEdit' : undefined,
65 tdCls
: 'pve-itype-icon-processor',
67 multiKey
: ['sockets', 'cpu', 'cores', 'numa', 'vcpus', 'cpulimit', 'cpuunits'],
68 renderer: function(value
, metaData
, record
, rowIndex
, colIndex
, store
, pending
) {
70 var sockets
= me
.getObjectValue('sockets', 1, pending
);
71 var model
= me
.getObjectValue('cpu', undefined, pending
);
72 var cores
= me
.getObjectValue('cores', 1, pending
);
73 var numa
= me
.getObjectValue('numa', undefined, pending
);
74 var vcpus
= me
.getObjectValue('vcpus', undefined, pending
);
75 var cpulimit
= me
.getObjectValue('cpulimit', undefined, pending
);
76 var cpuunits
= me
.getObjectValue('cpuunits', undefined, pending
);
78 var res
= (sockets
*cores
) + ' (' + sockets
+ ' sockets, ' + cores
+ ' cores)';
81 res
+= ' [' + model
+ ']';
85 res
+= ' [numa=' + numa
+']';
89 res
+= ' [vcpus=' + vcpus
+']';
93 res
+= ' [cpulimit=' + cpulimit
+']';
97 res
+= ' [cpuunits=' + cpuunits
+']';
104 header
: gettext('Keyboard Layout'),
106 editor
: caps
.vms
['VM.Config.Options'] ? 'PVE.qemu.KeyboardEdit' : undefined,
107 tdCls
: 'pve-itype-icon-keyboard',
109 renderer
: PVE
.Utils
.render_kvm_language
112 header
: gettext('Display'),
113 editor
: caps
.vms
['VM.Config.HWType'] ? 'PVE.qemu.DisplayEdit' : undefined,
115 tdCls
: 'pve-itype-icon-display',
117 renderer
: PVE
.Utils
.render_kvm_vga_driver
149 for (i
= 0; i
< 4; i
++) {
153 tdCls
: 'pve-itype-icon-storage',
154 editor
: 'PVE.qemu.HDEdit',
155 never_delete
: caps
.vms
['VM.Config.Disk'] ? false : true,
156 header
: gettext('Hard Disk') + ' (' + confid
+')',
157 cdheader
: gettext('CD/DVD Drive') + ' (' + confid
+')'
160 for (i
= 0; i
< 6; i
++) {
164 tdCls
: 'pve-itype-icon-storage',
165 editor
: 'PVE.qemu.HDEdit',
166 never_delete
: caps
.vms
['VM.Config.Disk'] ? false : true,
167 header
: gettext('Hard Disk') + ' (' + confid
+')',
168 cdheader
: gettext('CD/DVD Drive') + ' (' + confid
+')'
171 for (i
= 0; i
< 16; i
++) {
175 tdCls
: 'pve-itype-icon-storage',
176 editor
: 'PVE.qemu.HDEdit',
177 never_delete
: caps
.vms
['VM.Config.Disk'] ? false : true,
178 header
: gettext('Hard Disk') + ' (' + confid
+')',
179 cdheader
: gettext('CD/DVD Drive') + ' (' + confid
+')'
182 for (i
= 0; i
< 16; i
++) {
183 confid
= "virtio" + i
;
186 tdCls
: 'pve-itype-icon-storage',
187 editor
: 'PVE.qemu.HDEdit',
188 never_delete
: caps
.vms
['VM.Config.Disk'] ? false : true,
189 header
: gettext('Hard Disk') + ' (' + confid
+')',
190 cdheader
: gettext('CD/DVD Drive') + ' (' + confid
+')'
193 for (i
= 0; i
< 32; i
++) {
197 tdCls
: 'pve-itype-icon-network',
198 editor
: caps
.vms
['VM.Config.Network'] ? 'PVE.qemu.NetworkEdit' : undefined,
199 never_delete
: caps
.vms
['VM.Config.Network'] ? false : true,
200 header
: gettext('Network Device') + ' (' + confid
+')'
205 tdCls
: 'pve-itype-icon-storage',
207 never_delete
: caps
.vms
['VM.Config.Disk'] ? false : true,
208 header
: gettext('EFI Disk')
210 for (i
= 0; i
< 8; i
++) {
211 rows
["unused" + i
] = {
213 tdCls
: 'pve-itype-icon-storage',
214 editor
: caps
.vms
['VM.Config.Disk'] ? 'PVE.qemu.HDEdit' : undefined,
215 header
: gettext('Unused Disk') + ' ' + i
219 var sorterFn = function(rec1
, rec2
) {
220 var v1
= rec1
.data
.key
;
221 var v2
= rec2
.data
.key
;
222 var g1
= rows
[v1
].group
|| 0;
223 var g2
= rows
[v2
].group
|| 0;
226 (g1
> g2
? 1 : -1) : (v1
> v2
? 1 : (v1
< v2
? -1 : 0));
229 var reload = function() {
233 var baseurl
= 'nodes/' + nodename
+ '/qemu/' + vmid
+ '/config';
235 var sm
= Ext
.create('Ext.selection.RowModel', {});
237 var run_editor = function() {
238 var rec
= sm
.getSelection()[0];
243 var rowdef
= rows
[rec
.data
.key
];
244 if (!rowdef
.editor
) {
248 var editor
= rowdef
.editor
;
249 if (rowdef
.tdCls
== 'pve-itype-icon-storage') {
250 var value
= me
.getObjectValue(rec
.data
.key
, '', true);
251 if (value
.match(/media=cdrom/)) {
252 editor
= 'PVE.qemu.CDEdit';
258 if (Ext
.isString(editor
)) {
259 win
= Ext
.create(editor
, {
260 pveSelNode
: me
.pveSelNode
,
261 confid
: rec
.data
.key
,
262 url
: '/api2/extjs/' + baseurl
265 var config
= Ext
.apply({
266 pveSelNode
: me
.pveSelNode
,
267 confid
: rec
.data
.key
,
268 url
: '/api2/extjs/' + baseurl
270 win
= Ext
.createWidget(rowdef
.editor
.xtype
, config
);
275 win
.on('destroy', reload
);
278 var run_diskthrottle = function() {
279 var rec
= sm
.getSelection()[0];
284 var win
= Ext
.create('PVE.qemu.HDThrottle', {
285 pveSelNode
: me
.pveSelNode
,
286 confid
: rec
.data
.key
,
287 url
: '/api2/extjs/' + baseurl
291 win
.on('destroy', reload
);
294 var run_resize = function() {
295 var rec
= sm
.getSelection()[0];
300 var win
= Ext
.create('PVE.window.HDResize', {
308 win
.on('destroy', reload
);
311 var run_cpuoptions = function() {
312 var sockets
= me
.getObjectValue('sockets', 1);
313 var cores
= me
.getObjectValue('cores', 1);
315 var win
= Ext
.create('PVE.qemu.CPUOptions', {
316 maxvcpus
: sockets
* cores
,
318 pveSelNode
: me
.pveSelNode
,
319 url
: '/api2/extjs/' + baseurl
324 win
.on('destroy', reload
);
327 var run_move = function() {
328 var rec
= sm
.getSelection()[0];
333 var win
= Ext
.create('PVE.window.HDMove', {
341 win
.on('destroy', reload
);
344 var edit_btn
= new PVE
.button
.Button({
345 text
: gettext('Edit'),
351 var resize_btn
= new PVE
.button
.Button({
352 text
: gettext('Resize disk'),
358 var move_btn
= new PVE
.button
.Button({
359 text
: gettext('Move disk'),
365 var diskthrottle_btn
= new PVE
.button
.Button({
366 text
: gettext('Disk Throttle'),
369 handler
: run_diskthrottle
372 var cpuoptions_btn
= new Ext
.Button({
373 text
: gettext('CPU options'),
374 handler
: run_cpuoptions
377 var remove_btn
= new PVE
.button
.Button({
378 text
: gettext('Remove'),
382 confirmMsg: function(rec
) {
383 var msg
= Ext
.String
.format(gettext('Are you sure you want to remove entry {0}'),
384 "'" + me
.renderKey(rec
.data
.key
, {}, rec
) + "'");
385 if (rec
.data
.key
.match(/^unused\d+$/)) {
386 msg
+= " " + gettext('This will permanently erase all data.');
391 handler: function(b
, e
, rec
) {
392 PVE
.Utils
.API2Request({
393 url
: '/api2/extjs/' + baseurl
,
397 'delete': rec
.data
.key
399 callback: function() {
402 failure: function (response
, opts
) {
403 Ext
.Msg
.alert('Error', response
.htmlStatus
);
409 var revert_btn
= new PVE
.button
.Button({
410 text
: gettext('Revert'),
413 handler: function(b
, e
, rec
) {
414 var rowdef
= me
.rows
[rec
.data
.key
] || {};
415 var keys
= rowdef
.multiKey
|| [ rec
.data
.key
];
416 var revert
= keys
.join(',');
417 PVE
.Utils
.API2Request({
418 url
: '/api2/extjs/' + baseurl
,
424 callback: function() {
427 failure: function (response
, opts
) {
428 Ext
.Msg
.alert('Error',response
.htmlStatus
);
434 var efidisk_menuitem
= Ext
.create('Ext.menu.Item',{
435 text
: gettext('EFI Disk'),
436 iconCls
: 'pve-itype-icon-storage',
437 disabled
: !caps
.vms
['VM.Config.Disk'],
438 handler: function() {
439 var win
= Ext
.create('PVE.qemu.EFIDiskEdit', {
440 url
: '/api2/extjs/' + baseurl
,
441 pveSelNode
: me
.pveSelNode
443 win
.on('destroy', reload
);
448 var set_button_status = function() {
449 var sm
= me
.getSelectionModel();
450 var rec
= sm
.getSelection()[0];
452 // check if there is already an efidisk
453 var rstoredata
= me
.rstore
.getData().map
;
454 if (rstoredata
.bios
&&
455 rstoredata
.bios
.data
.value
=== 'ovmf' &&
456 !rstoredata
.efidisk0
) {
457 // we have ovmf configured and no efidisk
458 efidisk_menuitem
.setDisabled(false);
460 efidisk_menuitem
.setDisabled(true);
464 remove_btn
.disable();
466 resize_btn
.disable();
468 diskthrottle_btn
.disable();
469 revert_btn
.disable();
472 var key
= rec
.data
.key
;
473 var value
= rec
.data
.value
;
474 var rowdef
= rows
[key
];
476 var pending
= rec
.data
['delete'] || me
.hasPendingChanges(key
);
477 var isDisk
= !key
.match(/^unused\d+/) &&
478 rowdef
.tdCls
== 'pve-itype-icon-storage' &&
479 (value
&& !value
.match(/media=cdrom/));
481 var isEfi
= (key
=== 'efidisk0');
484 remove_btn
.setDisabled(rec
.data
['delete'] || (rowdef
.never_delete
=== true));
486 edit_btn
.setDisabled(rec
.data
['delete'] || !rowdef
.editor
);
488 resize_btn
.setDisabled(pending
|| !isDisk
);
490 move_btn
.setDisabled(pending
|| !isDisk
);
492 diskthrottle_btn
.setDisabled(pending
|| !isDisk
|| isEfi
);
494 revert_btn
.setDisabled(!pending
);
499 url
: '/api2/json/' + 'nodes/' + nodename
+ '/qemu/' + vmid
+ '/pending',
504 text
: gettext('Add'),
505 menu
: new Ext
.menu
.Menu({
508 text
: gettext('Hard Disk'),
509 iconCls
: 'pve-itype-icon-storage',
510 disabled
: !caps
.vms
['VM.Config.Disk'],
511 handler: function() {
512 var win
= Ext
.create('PVE.qemu.HDEdit', {
513 url
: '/api2/extjs/' + baseurl
,
514 pveSelNode
: me
.pveSelNode
516 win
.on('destroy', reload
);
521 text
: gettext('CD/DVD Drive'),
522 iconCls
: 'pve-itype-icon-cdrom',
523 disabled
: !caps
.vms
['VM.Config.Disk'],
524 handler: function() {
525 var win
= Ext
.create('PVE.qemu.CDEdit', {
526 url
: '/api2/extjs/' + baseurl
,
527 pveSelNode
: me
.pveSelNode
529 win
.on('destroy', reload
);
534 text
: gettext('Network Device'),
535 iconCls
: 'pve-itype-icon-network',
536 disabled
: !caps
.vms
['VM.Config.Network'],
537 handler: function() {
538 var win
= Ext
.create('PVE.qemu.NetworkEdit', {
539 url
: '/api2/extjs/' + baseurl
,
540 pveSelNode
: me
.pveSelNode
542 win
.on('destroy', reload
);
561 itemdblclick
: run_editor
,
562 selectionchange
: set_button_status
568 me
.on('activate', me
.rstore
.startUpdate
);
569 me
.on('destroy', me
.rstore
.stopUpdate
);
571 me
.mon(me
.rstore
, 'refresh', function() {