]> git.proxmox.com Git - pve-manager.git/commitdiff
add novnc console to workspace
authorStefan Priebe <s.priebe@profihost.ag>
Mon, 2 Jun 2014 07:43:37 +0000 (09:43 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Fri, 13 Jun 2014 09:03:06 +0000 (11:03 +0200)
Signed-off-by: Stefan Priebe <s.priebe@profihost.ag>
www/manager/VNCConsole.js
www/manager/Workspace.js
www/manager/button/ConsoleButton.js

index fba07ffe1d0f4de3f6469e1c188b26027bd037b1..e8c869d4cb3d6874a9ad32fa04f60560eb7702c3 100644 (file)
@@ -468,3 +468,236 @@ Ext.define('PVE.Shell', {
        me.callParent();
     }
 });
+
+Ext.define('PVE.noVNCConsole', {
+    extend: 'Ext.panel.Panel',
+    alias: ['widget.pvenoVNCConsole'],
+
+    initComponent : function() {
+       var me = this;
+
+       if (!me.url) {
+           throw "no url specified";
+       }
+
+       var myid = me.id + "-vncapp";
+
+       var box = Ext.create('widget.uxiframe', {
+                   id: myid
+               });
+
+       var resize_window = function() {
+           //console.log("resize");
+
+           var novnciframe = box.getFrame();
+           // console.log("resize " + myid + " " + novnciframe);
+           // noVNC_canvas
+           var tbar = me.getDockedItems("[dock=top]")[0];
+           var tbh = tbar ? tbar.getHeight() : 0;
+
+           // does not work as ExtJS modifies our iframe id from below
+           var innerDoc = novnciframe.contentDocument || novnciframe.contentWindow.document;
+
+           var aw = innerDoc.getElementById('noVNC_canvas').width + 8;
+           var ah = innerDoc.getElementById('noVNC_canvas').height + 8;
+
+           if (aw < 640) { aw = 640; }
+           if (ah < 400) { ah = 400; }
+
+           var oh;
+           var ow;
+
+           //console.log("size0 " + aw + " " + ah + " tbh " + tbh);
+
+           if (window.innerHeight) {
+               oh = window.innerHeight;
+               ow = window.innerWidth;
+           } else if (document.documentElement && 
+                      document.documentElement.clientHeight) {
+               oh = document.documentElement.clientHeight;
+               ow = document.documentElement.clientWidth;
+           } else if (document.body) {
+               oh = document.body.clientHeight;
+               ow = document.body.clientWidth;
+           }  else {
+               throw "can't get window size";
+           }
+
+           var offsetw = aw - ow;
+           var offseth = ah + tbh - oh;
+
+           if (offsetw !== 0 || offseth !== 0) {
+               //console.log("try resize by " + offsetw + " " + offseth);
+               try { window.resizeBy(offsetw, offseth); } catch (e) {}
+           }
+
+           Ext.Function.defer(resize_window, 1000);
+       };
+
+       var start_novnc_viewer = function(param) {
+
+           var urlparams = Ext.urlEncode({
+               encrypt: 1,
+               port: param.port,
+               password: param.ticket
+           });
+           box.load('/novnc/vnc_pve.html?' + urlparams);
+            if (me.toplevel) {
+               Ext.Function.defer(resize_window, 1000);
+           }
+       };
+
+       Ext.apply(me, {
+           layout: 'fit',
+           border: false,
+           autoScroll: me.toplevel ? false : true,
+           items: box,
+           reloadnoVNC: function() {
+               PVE.Utils.API2Request({
+                   url: me.url,
+                   params: me.params,
+                   method: me.method || 'POST',
+                   failure: function(response, opts) {
+                       box.update(gettext('Error') + ' ' + response.htmlStatus);
+                   },
+                   success: function(response, opts) {
+                       start_novnc_viewer(response.result.data);
+                   }
+               });
+           }
+       });
+
+       me.callParent();
+
+       if (me.toplevel) {
+           me.on("render", function() { me.reloadnoVNC();});
+       } else {
+           me.on("show", function() { me.reloadnoVNC();});
+           me.on("hide", function() { box.update(""); });
+       }
+    }
+});
+
+Ext.define('PVE.novncConsole', {
+    extend: 'PVE.noVNCConsole',
+    alias: ['widget.pvenovncConsole'],
+
+    initComponent : function() {
+       var me = this;
+       if (!me.nodename) { 
+           throw "no node name specified";
+       }
+
+       if (!me.vmid) {
+           throw "no VM ID specified";
+       }
+
+       var vm_command = function(cmd, params, reload) {
+           PVE.Utils.API2Request({
+               params: params,
+               url: '/nodes/' + me.nodename + '/qemu/' + me.vmid + "/status/" + cmd,
+               method: 'POST',
+               waitMsgTarget: me,
+               failure: function(response, opts) {
+                   Ext.Msg.alert('Error', response.htmlStatus);
+               },
+               success: function() {
+                   if (reload) {
+                       Ext.Function.defer(me.reloadnoVNC, 1000, me);
+                   }
+               }
+           });
+       };
+
+       var tbar = [ 
+           { 
+               text: gettext('Start'),
+               handler: function() { 
+                   vm_command("start", {}, 1);
+               }
+           },
+           { 
+               text: gettext('Shutdown'),
+               handler: function() {
+                   var msg = Ext.String.format(gettext("Do you really want to shutdown VM {0}?"), me.vmid);
+                   Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
+                       if (btn !== 'yes') {
+                           return;
+                       }
+                       vm_command('shutdown');
+                   });
+               }                           
+           }, 
+           { 
+               text: gettext('Kill VM'),
+               handler: function() {
+                   var msg = Ext.String.format(gettext("Do you really want to KILL VM {0}? This can cause data loss!"), me.vmid);
+                   Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
+                       if (btn !== 'yes') {
+                           return;
+                       }
+                       vm_command("stop");
+                   }); 
+               }
+           },
+           { 
+               xtype: 'pveQemuSendKeyMenu',
+               nodename: me.nodename,
+               vmid: me.vmid
+           },
+           { 
+               text: gettext('Reset'),
+               handler: function() { 
+                   var msg = Ext.String.format(gettext("Do you really want to reset VM {0}?"), me.vmid);
+                   Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
+                       if (btn !== 'yes') {
+                           return;
+                       }
+                       vm_command("reset");
+                   });
+               }
+           },
+           { 
+               text: gettext('Suspend'),
+               handler: function() {
+                   var msg = Ext.String.format(gettext("Do you really want to suspend VM {0}?"), me.vmid);
+                   Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
+                       if (btn !== 'yes') {
+                           return;
+                       }
+                       vm_command("suspend");
+                   }); 
+               }
+           },
+           { 
+               text: gettext('Resume'),
+               handler: function() {
+                   vm_command("resume"); 
+               }
+           },
+           // Note: no migrate here, because we can't display migrate log
+            { 
+                text: gettext('Console'),
+                handler: function() {
+                   PVE.Utils.openConsoleWindow('kvm', me.vmid, me.nodename, me.vmname);
+               }
+            },
+            '->',
+           {
+                text: gettext('Reload'),
+                handler: function () { 
+                   me.reloadnoVNC(); 
+               }
+           }
+       ];
+
+       Ext.apply(me, {
+           tbar: tbar,
+           url: "/nodes/" + me.nodename + "/qemu/" + me.vmid + "/vncproxy",
+           params: { unsecure: 1, websocket: 1 }
+       });
+
+       me.callParent();
+    }
+});
index 3a99c80aa42bdd97a77d6a443eb9016be7595de4..5efb509c849596c417403e0194a2f684b38b3dbe 100644 (file)
@@ -129,6 +129,18 @@ Ext.define('PVE.ConsoleWorkspace', {
                vmname: param.vmname,
                toplevel: true
            };
+       } else if (consoleType === 'novnc') {
+           me.title = "VM " + param.vmid;
+           if (param.vmname) {
+               me.title += " ('" + param.vmname + "')";
+           }
+           content = {
+               xtype: 'pvenovncConsole',
+               vmid: param.vmid,
+               nodename: param.node,
+               vmname: param.vmname,
+               toplevel: true
+           };
        } else if (consoleType === 'openvz') {
            me.title = "CT " + param.vmid;
            if (param.vmname) {
index 6dd45d8ff169a4e4791ad5f899c31efb5ce4ced2..23cfd749ae003125c8f3973643edec79fa490fce 100644 (file)
@@ -71,6 +71,12 @@ Ext.define('PVE.button.ConsoleButton', {
            }
        };
 
+       var create_novnc_console = function() {
+           if (me.consoleType === 'kvm') {
+               PVE.Utils.openConsoleWindow('novnc', me.vmid, me.nodename, me.consoleName);
+           }
+       };
+
        var create_vnc_console = function() {
            if (me.consoleType === 'kvm') {
                PVE.Utils.openConsoleWindow('kvm', me.vmid, me.nodename, me.consoleName);
@@ -97,6 +103,12 @@ Ext.define('PVE.button.ConsoleButton', {
            handler: create_vnc_console
        });
 
+       var novncMenu = Ext.create('Ext.menu.Item', {
+           text: 'noVNC',
+           iconCls: 'pve-itype-icon-novnc',
+           handler: create_novnc_console
+       });
+
        Ext.applyIf(me, { text: gettext('Console') });
 
        Ext.apply(me, {
@@ -109,7 +121,7 @@ Ext.define('PVE.button.ConsoleButton', {
                }
            },
            menu: new Ext.menu.Menu({
-               items: [ vncMenu, me.spiceMenu ]
+               items: [ novncMenu, vncMenu, me.spiceMenu ]
            })
        });