]>
git.proxmox.com Git - pve-xtermjs.git/blob - src/www/main.js
4da40b09305dd51e9990271110cb7a0796db363b
1 console
.log('xtermjs: starting');
20 starttime
= new Date();
22 var type
= getQueryParameter('console');
23 var vmid
= getQueryParameter('vmid');
24 var vmname
= getQueryParameter('vmname');
25 var nodename
= getQueryParameter('node');
26 var cmd
= getQueryParameter('cmd');
27 var cmdOpts
= getQueryParameter('cmd-opts');
29 function updateState(newState
, msg
) {
30 var timeout
, severity
, message
;
32 case states
.connecting
:
33 message
= "Connecting...";
35 severity
= severities
.warning
;
37 case states
.connected
:
38 message
= "Connected";
40 case states
.disconnecting
:
41 message
= "Disconnecting...";
43 severity
= severities
.warning
;
45 case states
.reconnecting
:
46 message
= "Reconnecting...";
48 severity
= severities
.warning
;
50 case states
.disconnected
:
53 case states
.connecting
:
54 case states
.reconnecting
:
55 message
= "Connection failed";
57 severity
= severities
.error
;
59 case states
.connected
:
60 case states
.disconnecting
:
61 var time_since_started
= new Date() - starttime
;
63 if (time_since_started
> 5*1000 || type
=== 'shell') {
64 message
= "Connection closed";
66 message
= "Connection failed";
67 severity
= severities
.error
;
70 case states
.disconnected
:
74 throw "unknown state";
78 throw "unknown state";
81 message
+= " (" + msg
+ ")";
84 showMsg(message
, timeout
, severity
);
87 var terminalContainer
= document
.getElementById('terminal-container');
88 document
.getElementById('status_bar').addEventListener('click', hideMsg
);
89 const fitAddon
= new FitAddon
.FitAddon();
93 function createTerminal() {
94 term
= new Terminal(getTerminalSettings());
95 term
.loadAddon(fitAddon
);
97 term
.onResize(function (size
) {
98 if (state
=== states
.connected
) {
99 socket
.send("1:" + size
.cols
+ ":" + size
.rows
+ ":");
103 protocol
= (location
.protocol
=== 'https:') ? 'wss://' : 'ws://';
106 var url
= '/nodes/' + nodename
;
109 url
+= '/qemu/' + vmid
;
112 url
+= '/lxc/' + vmid
;
115 params
.cmd
= 'upgrade';
118 params
.cmd
= decodeURI(cmd
);
119 if (cmdOpts
!== undefined) {
120 params
['cmd-opts'] = decodeURI(cmdOpts
);
127 url
: url
+ '/termproxy',
128 success: function(result
) {
129 var port
= encodeURIComponent(result
.data
.port
);
130 ticket
= result
.data
.ticket
;
131 socketURL
= protocol
+ location
.hostname
+ ((location
.port
) ? (':' + location
.port
) : '') + '/api2/json' + url
+ '/vncwebsocket?port=' + port
+ '&vncticket=' + encodeURIComponent(ticket
);
133 term
.open(terminalContainer
, true);
134 socket
= new WebSocket(socketURL
, 'binary');
135 socket
.binaryType
= 'arraybuffer';
136 socket
.onopen
= runTerminal
;
137 socket
.onclose
= tryReconnect
;
138 socket
.onerror
= tryReconnect
;
139 window
.onbeforeunload
= stopTerminal
;
140 updateState(states
.connecting
);
142 failure: function(msg
) {
143 updateState(states
.disconnected
,msg
);
149 function runTerminal() {
150 socket
.onmessage = function(event
) {
151 var answer
= new Uint8Array(event
.data
);
152 if (state
=== states
.connected
) {
154 } else if(state
=== states
.connecting
) {
155 if (answer
[0] === 79 && answer
[1] === 75) { // "OK"
156 updateState(states
.connected
);
157 term
.write(answer
.slice(2));
164 term
.onData(function(data
) {
165 if (state
=== states
.connected
) {
166 socket
.send("0:" + unescape(encodeURIComponent(data
)).length
.toString() + ":" + data
);
170 ping
= setInterval(function() {
174 window
.addEventListener('resize', function() {
175 clearTimeout(resize
);
176 resize
= setTimeout(function() {
182 socket
.send(PVE
.UserName
+ ':' + ticket
+ "\n");
184 // initial focus and resize
185 setTimeout(function() {
191 function getLxcStatus(callback
) {
194 url
: '/nodes/' + nodename
+ '/lxc/' + vmid
+ '/status/current',
195 success: function(result
) {
196 if (typeof callback
=== 'function') {
197 callback(true, result
);
200 failure: function(msg
) {
201 if (typeof callback
=== 'function') {
202 callback(false, msg
);
208 function checkMigration() {
210 if (apitype
=== 'kvm') {
218 url
: '/cluster/resources',
219 success: function(result
) {
220 // if not yet migrated , wait and try again
221 // if not migrating and stopped, cancel
222 // if started, connect
223 result
.data
.forEach(function(entity
) {
224 if (entity
.id
=== (apitype
+ '/' + vmid
)) {
225 var started
= entity
.status
=== 'running';
226 var migrated
= entity
.node
!== nodename
;
229 // goto different node
230 location
.href
= '?console=' + type
+
231 '&xtermjs=1&vmid=' + vmid
+ '&vmname=' +
232 vmname
+ '&node=' + entity
.node
;
235 updateState(states
.reconnecting
, 'waiting for migration to finish...');
236 setTimeout(checkMigration
, 5000);
239 if (type
=== 'lxc') {
240 // we have to check the status of the
241 // container to know if it has the
243 getLxcStatus(function(success
, result
) {
245 if (result
.data
.lock
=== 'migrate') {
247 updateState(states
.reconnecting
, 'waiting for migration to finish...');
248 setTimeout(checkMigration
, 5000);
249 } else if (started
) {
250 // container was rebooted
256 // probably the status call failed because
257 // the ct is already somewhere else, so retry
258 setTimeout(checkMigration
, 1000);
261 } else if (started
) {
262 // this happens if we have old data in
263 // /cluster/resources, or the connection
264 // disconnected, so simply try to reload here
266 } else if (type
=== 'kvm') {
267 // it seems the guest simply stopped
276 failure: function(msg
) {
277 errorTerminal({msg
: msg
});
282 function tryReconnect() {
283 var time_since_started
= new Date() - starttime
;
284 var type
= getQueryParameter('console');
285 if (time_since_started
< 5*1000 || type
=== 'shell' || type
=== 'cmd') { // 5 seconds
290 updateState(states
.disconnecting
, 'Detecting migration...');
291 setTimeout(checkMigration
, 5000);
294 function clearEvents() {
295 term
.onResize(() => {});
296 term
.onData(() => {});
299 function stopTerminal(event
) {
304 updateState(states
.disconnected
, event
.msg
+ event
.code
);
307 function errorTerminal(event
) {
313 updateState(states
.disconnected
, event
.msg
+ event
.code
);