]> git.proxmox.com Git - pve-manager.git/commitdiff
copy qemu/HardwareView.js from manager to manager6
authorDietmar Maurer <dietmar@proxmox.com>
Wed, 16 Mar 2016 08:12:22 +0000 (09:12 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Wed, 16 Mar 2016 08:12:22 +0000 (09:12 +0100)
www/manager6/qemu/HardwareView.js [new file with mode: 0644]

diff --git a/www/manager6/qemu/HardwareView.js b/www/manager6/qemu/HardwareView.js
new file mode 100644 (file)
index 0000000..89f2f4e
--- /dev/null
@@ -0,0 +1,537 @@
+// fixme: howto avoid jslint type confusion?
+/*jslint confusion: true */
+Ext.define('PVE.qemu.HardwareView', {
+    extend: 'PVE.grid.PendingObjectGrid',
+    alias: ['widget.PVE.qemu.HardwareView'],
+
+    renderKey: function(key, metaData, rec, rowIndex, colIndex, store) {
+       var me = this;
+       var rows = me.rows;
+       var rowdef = rows[key] || {};
+
+       metaData.tdAttr = "valign=middle";
+
+       if (rowdef.tdCls) {
+           metaData.tdCls = rowdef.tdCls;
+           if (rowdef.tdCls == 'pve-itype-icon-storage') { 
+               var value = me.getObjectValue(key, '', true);
+               if (value.match(/media=cdrom/)) {
+                   metaData.tdCls = 'pve-itype-icon-cdrom';
+                   return rowdef.cdheader;
+               }
+           }
+       }
+       return rowdef.header || key;
+    },
+
+    initComponent : function() {
+       var me = this;
+       var i, confid;
+
+       var nodename = me.pveSelNode.data.node;
+       if (!nodename) { 
+           throw "no node name specified";
+       }
+
+       var vmid = me.pveSelNode.data.vmid;
+       if (!vmid) {
+           throw "no VM ID specified";
+       }
+
+       var caps = Ext.state.Manager.get('GuiCap');
+
+       var rows = {
+           memory: {
+               header: gettext('Memory'),
+               editor: caps.vms['VM.Config.Memory'] ? 'PVE.qemu.MemoryEdit' : undefined,
+               never_delete: true,
+               defaultValue: 512,
+               tdCls: 'pve-itype-icon-memory',
+               renderer: function(value, metaData, record) {
+                   var balloon =  me.getObjectValue('balloon');
+                   if (balloon) {
+                       return PVE.Utils.format_size(balloon*1024*1024) + "/" + 
+                           PVE.Utils.format_size(value*1024*1024);
+
+                   } 
+                   return PVE.Utils.format_size(value*1024*1024);
+               }
+           },
+           sockets: {
+               header: gettext('Processors'),
+               never_delete: true,
+               editor: (caps.vms['VM.Config.CPU'] || caps.vms['VM.Config.HWType']) ? 
+                   'PVE.qemu.ProcessorEdit' : undefined,
+               tdCls: 'pve-itype-icon-processor',
+               defaultValue: 1,
+               multiKey: ['sockets', 'cpu', 'cores', 'numa', 'vcpus', 'cpulimit', 'cpuunits'],
+               renderer: function(value, metaData, record, rowIndex, colIndex, store, pending) {
+
+                   var sockets = me.getObjectValue('sockets', 1, pending);
+                   var model = me.getObjectValue('cpu', undefined, pending);
+                   var cores = me.getObjectValue('cores', 1, pending);
+                   var numa = me.getObjectValue('numa', undefined, pending);
+                   var vcpus = me.getObjectValue('vcpus', undefined, pending);
+                   var cpulimit = me.getObjectValue('cpulimit', undefined, pending);
+                   var cpuunits = me.getObjectValue('cpuunits', undefined, pending);
+
+                   var res = (sockets*cores) + ' (' + sockets + ' sockets, ' + cores + ' cores)';
+                   
+                   if (model) {
+                       res += ' [' + model + ']';
+                   }
+
+                   if (numa) {
+                       res += ' [numa=' + numa +']';
+                   }
+
+                   if (vcpus) {
+                       res += ' [vcpus=' + vcpus +']';
+                   }
+
+                   if (cpulimit) {
+                       res += ' [cpulimit=' + cpulimit +']';
+                   }
+
+                   if (cpuunits) {
+                       res += ' [cpuunits=' + cpuunits +']';
+                   }
+
+                   return res;
+               }
+           },
+           keyboard: {
+               header: gettext('Keyboard Layout'),
+               never_delete: true,
+               editor: caps.vms['VM.Config.Options'] ? 'PVE.qemu.KeyboardEdit' : undefined,
+               tdCls: 'pve-itype-icon-keyboard',
+               defaultValue: '',
+               renderer: PVE.Utils.render_kvm_language
+           },
+           vga: {
+               header: gettext('Display'),
+               editor: caps.vms['VM.Config.HWType'] ? 'PVE.qemu.DisplayEdit' : undefined,
+               never_delete: true,
+               tdCls: 'pve-itype-icon-display',
+               defaultValue: '',
+               renderer: PVE.Utils.render_kvm_vga_driver               
+           },
+           cores: {
+               visible: false
+           },
+           cpu: {
+               visible: false
+           },
+           numa: {
+               visible: false
+           },
+           balloon: {
+               visible: false
+           },
+           hotplug: {
+               visible: false
+           },
+           vcpus: {
+               visible: false
+           },
+           cpuunits: {
+               visible: false
+           },
+           cpulimit: {
+               visible: false
+           }
+
+       };
+
+       for (i = 0; i < 4; i++) {
+           confid = "ide" + i;
+           rows[confid] = {
+               group: 1,
+               tdCls: 'pve-itype-icon-storage',
+               editor: 'PVE.qemu.HDEdit',
+               never_delete: caps.vms['VM.Config.Disk'] ? false : true,
+               header: gettext('Hard Disk') + ' (' + confid +')',
+               cdheader: gettext('CD/DVD Drive') + ' (' + confid +')'
+           };
+       }
+       for (i = 0; i < 6; i++) {
+           confid = "sata" + i;
+           rows[confid] = {
+               group: 1,
+               tdCls: 'pve-itype-icon-storage',
+               editor: 'PVE.qemu.HDEdit',
+               never_delete: caps.vms['VM.Config.Disk'] ? false : true,
+               header: gettext('Hard Disk') + ' (' + confid +')',
+               cdheader: gettext('CD/DVD Drive') + ' (' + confid +')'
+           };
+       }
+       for (i = 0; i < 16; i++) {
+           confid = "scsi" + i;
+           rows[confid] = {
+               group: 1,
+               tdCls: 'pve-itype-icon-storage',
+               editor: 'PVE.qemu.HDEdit',
+               never_delete: caps.vms['VM.Config.Disk'] ? false : true,
+               header: gettext('Hard Disk') + ' (' + confid +')',
+               cdheader: gettext('CD/DVD Drive') + ' (' + confid +')'
+           };
+       }
+       for (i = 0; i < 16; i++) {
+           confid = "virtio" + i;
+           rows[confid] = {
+               group: 1,
+               tdCls: 'pve-itype-icon-storage',
+               editor: 'PVE.qemu.HDEdit',
+               never_delete: caps.vms['VM.Config.Disk'] ? false : true,
+               header: gettext('Hard Disk') + ' (' + confid +')',
+               cdheader: gettext('CD/DVD Drive') + ' (' + confid +')'
+           };
+       }
+       for (i = 0; i < 32; i++) {
+           confid = "net" + i;
+           rows[confid] = {
+               group: 2,
+               tdCls: 'pve-itype-icon-network',
+               editor: caps.vms['VM.Config.Network'] ? 'PVE.qemu.NetworkEdit' : undefined,
+               never_delete: caps.vms['VM.Config.Network'] ? false : true,
+               header: gettext('Network Device') + ' (' + confid +')'
+           };
+       }
+       for (i = 0; i < 8; i++) {
+           rows["unused" + i] = {
+               group: 3,
+               tdCls: 'pve-itype-icon-storage',
+               editor: caps.vms['VM.Config.Disk'] ? 'PVE.qemu.HDEdit' : undefined,
+               header: gettext('Unused Disk') + ' ' + i
+           };
+       }
+
+       var sorterFn = function(rec1, rec2) {
+           var v1 = rec1.data.key;
+           var v2 = rec2.data.key;
+           var g1 = rows[v1].group || 0;
+           var g2 = rows[v2].group || 0;
+           
+           return (g1 !== g2) ? 
+               (g1 > g2 ? 1 : -1) : (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
+       };
+
+       var reload = function() {
+           me.rstore.load();
+       };
+
+       var baseurl = 'nodes/' + nodename + '/qemu/' + vmid + '/config';
+
+       var sm = Ext.create('Ext.selection.RowModel', {});
+
+       var run_editor = function() {
+           var rec = sm.getSelection()[0];
+           if (!rec) {
+               return;
+           }
+
+           var rowdef = rows[rec.data.key];
+           if (!rowdef.editor) {
+               return;
+           }
+
+           var editor = rowdef.editor;
+           if (rowdef.tdCls == 'pve-itype-icon-storage') {
+               var value = me.getObjectValue(rec.data.key, '', true); 
+               if (value.match(/media=cdrom/)) {
+                   editor = 'PVE.qemu.CDEdit';
+               }
+           }
+
+           var win;
+
+           if (Ext.isString(editor)) {
+               win = Ext.create(editor, {
+                   pveSelNode: me.pveSelNode,
+                   confid: rec.data.key,
+                   url: '/api2/extjs/' + baseurl
+               });
+           } else {
+               var config = Ext.apply({
+                   pveSelNode: me.pveSelNode,
+                   confid: rec.data.key,
+                   url: '/api2/extjs/' + baseurl
+               }, rowdef.editor);
+               win = Ext.createWidget(rowdef.editor.xtype, config);
+               win.load();
+           }
+
+           win.show();
+           win.on('destroy', reload);
+       };
+
+       var run_diskthrottle = function() {
+           var rec = sm.getSelection()[0];
+           if (!rec) {
+               return;
+           }
+
+            var win = Ext.create('PVE.qemu.HDThrottle', {
+               pveSelNode: me.pveSelNode,
+               confid: rec.data.key,
+               url: '/api2/extjs/' + baseurl
+           });
+
+           win.show();
+           win.on('destroy', reload);
+       };
+
+       var run_resize = function() {
+           var rec = sm.getSelection()[0];
+           if (!rec) {
+               return;
+           }
+
+           var win = Ext.create('PVE.window.HDResize', {
+               disk: rec.data.key,
+               nodename: nodename,
+               vmid: vmid
+           });
+
+           win.show();
+
+           win.on('destroy', reload);
+       };
+
+       var run_cpuoptions = function() {
+           var sockets = me.getObjectValue('sockets', 1);
+           var cores = me.getObjectValue('cores', 1);
+
+           var win = Ext.create('PVE.qemu.CPUOptions', {
+               maxvcpus: sockets * cores,
+               vmid: vmid,
+               pveSelNode: me.pveSelNode,
+               url: '/api2/extjs/' + baseurl
+           });
+
+           win.show();
+
+           win.on('destroy', reload);
+       };
+
+       var run_move = function() {
+           var rec = sm.getSelection()[0];
+           if (!rec) {
+               return;
+           }
+
+           var win = Ext.create('PVE.window.HDMove', {
+               disk: rec.data.key,
+               nodename: nodename,
+               vmid: vmid
+           });
+
+           win.show();
+
+           win.on('destroy', reload);
+       };
+
+       var edit_btn = new PVE.button.Button({
+           text: gettext('Edit'),
+           selModel: sm,
+           disabled: true,
+           handler: run_editor
+        });
+
+       var resize_btn = new PVE.button.Button({
+           text: gettext('Resize disk'),
+           selModel: sm,
+           disabled: true,
+           handler: run_resize
+       });
+
+       var move_btn = new PVE.button.Button({
+           text: gettext('Move disk'),
+           selModel: sm,
+           disabled: true,
+           handler: run_move
+       });
+
+       var diskthrottle_btn = new PVE.button.Button({
+           text: gettext('Disk Throttle'),
+           selModel: sm,
+           disabled: true,
+           handler: run_diskthrottle
+       });
+
+       var cpuoptions_btn = new Ext.Button({
+           text: gettext('CPU options'),
+           handler: run_cpuoptions
+       });
+
+       var remove_btn = new PVE.button.Button({
+           text: gettext('Remove'),
+           selModel: sm,
+           disabled: true,
+           dangerous: true,
+           confirmMsg: function(rec) {
+               var msg = Ext.String.format(gettext('Are you sure you want to remove entry {0}'),
+                                           "'" + me.renderKey(rec.data.key, {}, rec) + "'");
+               if (rec.data.key.match(/^unused\d+$/)) {
+                   msg += " " + gettext('This will permanently erase all image data.');
+               }
+
+               return msg;
+           },
+           handler: function(b, e, rec) {
+               PVE.Utils.API2Request({
+                   url: '/api2/extjs/' + baseurl,
+                   waitMsgTarget: me,
+                   method: 'PUT',
+                   params: {
+                       'delete': rec.data.key
+                   },
+                   callback: function() {
+                       reload();
+                   },
+                   failure: function (response, opts) {
+                       Ext.Msg.alert('Error', response.htmlStatus);
+                   }
+               });
+           }
+       });
+
+       var revert_btn = new PVE.button.Button({
+           text: gettext('Revert'),
+           selModel: sm,
+           disabled: true,
+           handler: function(b, e, rec) {
+               var rowdef = me.rows[rec.data.key] || {};
+               var keys = rowdef.multiKey ||  [ rec.data.key ];
+               var revert = keys.join(',');
+               PVE.Utils.API2Request({
+                   url: '/api2/extjs/' + baseurl,
+                   waitMsgTarget: me,
+                   method: 'PUT',
+                   params: {
+                       'revert': revert
+                   },
+                   callback: function() {
+                       reload();
+                   },
+                   failure: function (response, opts) {
+                       Ext.Msg.alert('Error',response.htmlStatus);
+                   }
+               });
+           }
+       });
+
+       var set_button_status = function() {
+           var sm = me.getSelectionModel();
+           var rec = sm.getSelection()[0];
+
+           if (!rec) {
+               remove_btn.disable();
+               edit_btn.disable();
+               resize_btn.disable();
+               move_btn.disable();
+               diskthrottle_btn.disable();
+               revert_btn.disable();
+               return;
+           }
+           var key = rec.data.key;
+           var value = rec.data.value;
+           var rowdef = rows[key];
+
+           var pending = rec.data['delete'] || me.hasPendingChanges(key);
+           var isDisk = !key.match(/^unused\d+/) && 
+               (rowdef.tdCls == 'pve-itype-icon-storage' && !value.match(/media=cdrom/));
+
+           remove_btn.setDisabled(rec.data['delete'] || (rowdef.never_delete === true));
+
+           edit_btn.setDisabled(rec.data['delete'] || !rowdef.editor);
+
+           resize_btn.setDisabled(pending || !isDisk);
+
+           move_btn.setDisabled(pending || !isDisk);
+
+           diskthrottle_btn.setDisabled(pending || !isDisk);
+
+           revert_btn.setDisabled(!pending);
+
+       };
+
+       Ext.applyIf(me, {
+           url: '/api2/json/' + 'nodes/' + nodename + '/qemu/' + vmid + '/pending',
+           interval: 5000,
+           selModel: sm,
+           cwidth1: 170,
+           tbar: [ 
+               {
+                   text: gettext('Add'),
+                   menu: new Ext.menu.Menu({
+                       items: [
+                           {
+                               text: gettext('Hard Disk'),
+                               iconCls: 'pve-itype-icon-storage',
+                               disabled: !caps.vms['VM.Config.Disk'],
+                               handler: function() {
+                                   var win = Ext.create('PVE.qemu.HDEdit', {
+                                       url: '/api2/extjs/' + baseurl,
+                                       pveSelNode: me.pveSelNode
+                                   });
+                                   win.on('destroy', reload);
+                                   win.show();
+                               }
+                           },
+                           {
+                               text: gettext('CD/DVD Drive'),
+                               iconCls: 'pve-itype-icon-cdrom',
+                               disabled: !caps.vms['VM.Config.Disk'],
+                               handler: function() {
+                                   var win = Ext.create('PVE.qemu.CDEdit', {
+                                       url: '/api2/extjs/' + baseurl,
+                                       pveSelNode: me.pveSelNode
+                                   });
+                                   win.on('destroy', reload);
+                                   win.show();
+                               }
+                           },
+                           {
+                               text: gettext('Network Device'),
+                               iconCls: 'pve-itype-icon-network',
+                               disabled: !caps.vms['VM.Config.Network'],
+                               handler: function() {
+                                   var win = Ext.create('PVE.qemu.NetworkEdit', {
+                                       url: '/api2/extjs/' + baseurl,
+                                       pveSelNode: me.pveSelNode
+                                   });
+                                   win.on('destroy', reload);
+                                   win.show();
+                               }
+                           }
+                       ]
+                   })
+               }, 
+               remove_btn,
+               edit_btn,
+               resize_btn,
+               move_btn,
+               diskthrottle_btn,
+               cpuoptions_btn,
+               revert_btn
+           ],
+           rows: rows,
+           sorterFn: sorterFn,
+           listeners: {
+               itemdblclick: run_editor,
+               selectionchange: set_button_status
+           }
+       });
+
+       me.callParent();
+
+       me.on('show', me.rstore.startUpdate);
+       me.on('hide', me.rstore.stopUpdate);
+       me.on('destroy', me.rstore.stopUpdate); 
+
+       me.rstore.on('datachanged', function() {
+           set_button_status();
+       });
+    }
+});