]> git.proxmox.com Git - pve-manager.git/blob - www/manager6/VNCConsole.js
ext6migrate: update vncconsole and remove java applet code
[pve-manager.git] / www / manager6 / VNCConsole.js
1 Ext.define('PVE.noVncConsole', {
2 extend: 'Ext.panel.Panel',
3 alias: 'widget.pveNoVncConsole',
4
5 nodename: undefined,
6
7 vmid: undefined,
8
9 consoleType: undefined, // lxc or kvm
10
11 layout: 'fit',
12
13 border: false,
14
15 initComponent : function() {
16 var me = this;
17
18 if (!me.nodename) {
19 throw "no node name specified";
20 }
21
22 if (!me.consoleType) {
23 throw "no console type specified";
24 }
25
26 if (!me.vmid && me.consoleType !== 'shell') {
27 throw "no VM ID specified";
28 }
29
30 // always use same iframe, to avoid running several noVnc clients
31 // at same time (to avoid performance problems)
32 var box = Ext.create('Ext.ux.IFrame', { id : "vncconsole" });
33
34 Ext.apply(me, {
35 items: box,
36 listeners: {
37 activate: function() {
38 var url = '/?console=' + me.consoleType + '&novnc=1&node=' + me.nodename + '&resize=scale';
39 if (me.vmid) {
40 url += '&vmid='+ me.vmid;
41 }
42 box.load(url);
43 }
44 }
45 });
46
47 me.callParent();
48 }
49 });
50
51 Ext.define('PVE.VNCConsole', {
52 extend: 'Ext.panel.Panel',
53 alias: ['widget.pveVNCConsole'],
54
55 last_novnc_state: undefined,
56 last_novnc_msg: undefined,
57
58 layout: 'fit',
59 border: false,
60
61 detectMigratedVM: function() {
62 var me = this;
63
64 if (!me.vmid) {
65 return;
66 }
67
68 // try to detect migrated VM
69 PVE.Utils.API2Request({
70 url: '/cluster/resources',
71 method: 'GET',
72 success: function(response) {
73 var list = response.result.data;
74 Ext.Array.each(list, function(item) {
75 if (item.type === 'qemu' && item.vmid == me.vmid) {
76 if (item.node !== me.nodename) {
77 me.nodename = item.node;
78 me.url = "/nodes/" + me.nodename + "/" + item.type + "/" + me.vmid + "/vncproxy";
79 me.wsurl = "/nodes/" + me.nodename + "/" + item.type + "/" + me.vmid + "/vncwebsocket";
80 me.reloadApplet();
81 }
82 return false; // break
83 }
84 });
85 }
86 });
87 },
88
89 initComponent : function() {
90 var me = this;
91
92 if (!me.url) {
93 throw "no url specified";
94 }
95
96 var myid = me.id + "-vncapp";
97
98 me.appletID = myid;
99
100 var box;
101
102 if (!me.wsurl) {
103 throw "no web socket url specified";
104 }
105 box = Ext.create('Ext.ux.IFrame', { id: myid });
106
107 var resize_window = function() {
108 //console.log("resize");
109
110 var aw;
111 var ah;
112
113 var novnciframe = box.getFrame();
114 // noVNC_canvas
115 var innerDoc = novnciframe.contentDocument || novnciframe.contentWindow.document;
116 aw = innerDoc.getElementById('noVNC_canvas').width;
117 ah = innerDoc.getElementById('noVNC_canvas').height + 8;
118
119 var novnc_state = innerDoc.getElementById('noVNC_status_state').innerHTML;
120 var novnc_msg = innerDoc.getElementById('noVNC_status_msg').innerHTML;
121
122 if (novnc_state !== me.last_novnc_state || novnc_msg !== me.last_novnc_msg) {
123 me.last_novnc_state = novnc_state;
124 me.last_novnc_msg = novnc_msg;
125
126 if (novnc_state !== 'normal') {
127 PVE.Utils.setErrorMask(box, novnc_msg || 'unknown');
128 } else {
129 PVE.Utils.setErrorMask(box); // clear mask
130 }
131
132 if (novnc_state === 'disconnected') {
133 me.detectMigratedVM();
134 }
135 }
136
137 if (aw < 640) { aw = 640; }
138 if (ah < 400) { ah = 400; }
139
140 var tbar = me.getDockedItems("[dock=top]")[0];
141 var tbh = tbar ? tbar.getHeight() : 0;
142
143 var oh;
144 var ow;
145
146 //console.log("size0 " + aw + " " + ah + " tbh " + tbh);
147
148 if (window.innerHeight) {
149 oh = window.innerHeight;
150 ow = window.innerWidth;
151 } else if (document.documentElement &&
152 document.documentElement.clientHeight) {
153 oh = document.documentElement.clientHeight;
154 ow = document.documentElement.clientWidth;
155 } else if (document.body) {
156 oh = document.body.clientHeight;
157 ow = document.body.clientWidth;
158 } else {
159 throw "can't get window size";
160 }
161
162 var offsetw = aw - ow;
163 var offseth = ah + tbh - oh;
164
165 if (offsetw !== 0 || offseth !== 0) {
166 //console.log("try resize by " + offsetw + " " + offseth);
167 try { window.resizeBy(offsetw, offseth); } catch (e) {}
168 }
169
170 Ext.Function.defer(resize_window, 1000);
171 };
172
173 var start_vnc_viewer = function(param) {
174 var pveparams = Ext.urlEncode({
175 port: param.port,
176 vncticket: param.ticket
177 });
178
179 var urlparams = Ext.urlEncode({
180 encrypt: 1,
181 path: "api2/json" + me.wsurl + "?" + pveparams,
182 password: param.ticket
183 });
184 box.load('/novnc/vnc_pve.html?' + urlparams);
185
186 Ext.Function.defer(resize_window, 1000);
187 };
188
189 Ext.apply(me, {
190 scrollable: me.toplevel ? false : true,
191 items: box,
192 reloadApplet: function() {
193 var params = Ext.apply({}, me.params);
194 params.websocket = 1;
195 PVE.Utils.API2Request({
196 url: me.url,
197 params: params,
198 method: me.method || 'POST',
199 failure: function(response, opts) {
200 box.update(gettext('Error') + ' ' + response.htmlStatus);
201 },
202 success: function(response, opts) {
203 start_vnc_viewer(response.result.data);
204 }
205 });
206 }
207 });
208
209 me.callParent();
210
211 if (me.toplevel) {
212 me.on("render", me.reloadApplet);
213 } else {
214 me.on("activate", me.reloadApplet);
215 me.on("hide", function() { box.update(""); });
216 }
217 }
218 });
219
220 Ext.define('PVE.KVMConsole', {
221 extend: 'PVE.VNCConsole',
222 alias: ['widget.pveKVMConsole'],
223
224 initComponent : function() {
225 var me = this;
226
227 if (!me.nodename) {
228 throw "no node name specified";
229 }
230
231 if (!me.vmid) {
232 throw "no VM ID specified";
233 }
234
235 var baseUrl = "/nodes/" + me.nodename + "/qemu/" + me.vmid;
236
237 var vm_command = function(cmd, params, reload_applet) {
238 PVE.Utils.API2Request({
239 params: params,
240 url: baseUrl + "/status/" + cmd,
241 method: 'POST',
242 waitMsgTarget: me,
243 failure: function(response, opts) {
244 Ext.Msg.alert('Error', response.htmlStatus);
245 },
246 success: function() {
247 if (reload_applet) {
248 Ext.Function.defer(me.reloadApplet, 1000, me);
249 }
250 }
251 });
252 };
253
254 var tbar = [
255 {
256 text: gettext('Start'),
257 handler: function() {
258 vm_command("start", {}, 1);
259 }
260 },
261 {
262 text: gettext('Shutdown'),
263 handler: function() {
264 var msg = Ext.String.format(gettext("Do you really want to shutdown VM {0}?"), me.vmid);
265 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
266 if (btn !== 'yes') {
267 return;
268 }
269 vm_command('shutdown');
270 });
271 }
272 },
273 {
274 text: gettext('Stop'),
275 handler: function() {
276 var msg = Ext.String.format(gettext("Do you really want to stop VM {0}?"), me.vmid);
277 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
278 if (btn !== 'yes') {
279 return;
280 }
281 vm_command("stop");
282 });
283 }
284 },
285 {
286 xtype: 'pveQemuSendKeyMenu',
287 nodename: me.nodename,
288 vmid: me.vmid
289 },
290 {
291 text: gettext('Reset'),
292 handler: function() {
293 var msg = Ext.String.format(gettext("Do you really want to reset VM {0}?"), me.vmid);
294 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
295 if (btn !== 'yes') {
296 return;
297 }
298 vm_command("reset");
299 });
300 }
301 },
302 {
303 text: gettext('Suspend'),
304 handler: function() {
305 var msg = Ext.String.format(gettext("Do you really want to suspend VM {0}?"), me.vmid);
306 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
307 if (btn !== 'yes') {
308 return;
309 }
310 vm_command("suspend");
311 });
312 }
313 },
314 {
315 text: gettext('Resume'),
316 handler: function() {
317 vm_command("resume");
318 }
319 },
320 // Note: no migrate here, because we can't display migrate log
321 {
322 text: gettext('Console'),
323 handler: function() {
324 PVE.Utils.openVNCViewer('kvm', me.vmid, me.nodename, me.vmname);
325 }
326 },
327 '->',
328 {
329 text: gettext('Reload'),
330 handler: function () {
331 me.reloadApplet();
332 }
333 }
334 ];
335
336
337 Ext.apply(me, {
338 tbar: tbar,
339 url: baseUrl + "/vncproxy",
340 wsurl: baseUrl + "/vncwebsocket"
341 });
342
343 me.callParent();
344 }
345 });
346
347 Ext.define('PVE.LxcConsole', {
348 extend: 'PVE.VNCConsole',
349 alias: ['widget.pveLxcConsole'],
350
351 initComponent : function() {
352 var me = this;
353
354 if (!me.nodename) {
355 throw "no node name specified";
356 }
357
358 if (!me.vmid) {
359 throw "no VM ID specified";
360 }
361
362 var baseUrl = "/nodes/" + me.nodename + "/lxc/" + me.vmid;
363
364 var vm_command = function(cmd, params, reload_applet) {
365 PVE.Utils.API2Request({
366 params: params,
367 url: baseUrl + "/status/" + cmd,
368 waitMsgTarget: me,
369 method: 'POST',
370 failure: function(response, opts) {
371 Ext.Msg.alert('Error', response.htmlStatus);
372 },
373 success: function() {
374 if (reload_applet) {
375 Ext.Function.defer(me.reloadApplet, 1000, me);
376 }
377 }
378 });
379 };
380
381 var tbar = [
382 {
383 text: gettext('Start'),
384 handler: function() {
385 vm_command("start");
386 }
387 },
388 {
389 text: gettext('Shutdown'),
390 handler: function() {
391 var msg = Ext.String.format(gettext("Do you really want to shutdown VM {0}?"), me.vmid);
392 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
393 if (btn !== 'yes') {
394 return;
395 }
396 vm_command("shutdown");
397 });
398 }
399 },
400 {
401 text: gettext('Stop'),
402 handler: function() {
403 var msg = Ext.String.format(gettext("Do you really want to stop VM {0}?"), me.vmid);
404 Ext.Msg.confirm(gettext('Confirm'), msg, function(btn) {
405 if (btn !== 'yes') {
406 return;
407 }
408 vm_command("stop");
409 });
410 }
411 },
412 // Note: no migrate here, because we can't display migrate log
413 '->',
414 {
415 text: gettext('Reload'),
416 handler: function () {
417 me.reloadApplet();
418 }
419 }
420 ];
421
422 Ext.apply(me, {
423 tbar: tbar,
424 url: baseUrl + "/vncproxy",
425 wsurl: baseUrl + "/vncwebsocket"
426 });
427
428 me.callParent();
429 }
430 });
431
432 Ext.define('PVE.Shell', {
433 extend: 'PVE.VNCConsole',
434 alias: ['widget.pveShell'],
435
436 ugradeSystem: false, // set to true to run "apt-get dist-upgrade"
437
438 initComponent : function() {
439 var me = this;
440
441 if (!me.nodename) {
442 throw "no node name specified";
443 }
444
445 var tbar = [ '->' ];
446
447 if (!me.ugradeSystem) {
448 // we dont want to restart the upgrade script
449 tbar.push({
450 text: gettext('Reload'),
451 handler: function () { me.reloadApplet(); }
452 });
453 }
454
455 tbar.push({
456 text: gettext('Shell'),
457 handler: function() {
458 PVE.Utils.openVNCViewer('shell', undefined, me.nodename, undefined);
459 }
460 });
461
462 var baseUrl = "/nodes/" + me.nodename;
463
464 Ext.apply(me, {
465 tbar: tbar,
466 url: baseUrl + "/vncshell",
467 wsurl: baseUrl + "/vncwebsocket"
468 });
469
470 if (me.ugradeSystem) {
471 me.params = { upgrade: 1 };
472 }
473
474 me.callParent();
475 }
476 });