X-Git-Url: https://git.proxmox.com/?p=pve-xtermjs.git;a=blobdiff_plain;f=src%2Fwww%2Fmain.js;fp=src%2Fwww%2Fmain.js;h=0000000000000000000000000000000000000000;hp=85cc39953c928bc2003323777069a49fca5078ab;hb=145da0bf450e9f6447c9dad2d6d967ea7f0ca011;hpb=13e2e50222d588fc9105276193cdbdc596b9feb9 diff --git a/src/www/main.js b/src/www/main.js deleted file mode 100644 index 85cc399..0000000 --- a/src/www/main.js +++ /dev/null @@ -1,386 +0,0 @@ -console.log('xtermjs: starting'); - -var states = { - start: 1, - connecting: 2, - connected: 3, - disconnecting: 4, - disconnected: 5, - reconnecting: 6, -}; - -var term, - protocol, - socketURL, - socket, - ticket, - resize, - ping, - state = states.start, - starttime = new Date(); - -var type = getQueryParameter('console'); -var vmid = getQueryParameter('vmid'); -var vmname = getQueryParameter('vmname'); -var nodename = getQueryParameter('node'); -var cmd = getQueryParameter('cmd'); -var cmdOpts = getQueryParameter('cmd-opts'); - -function updateState(newState, msg, code) { - var timeout, severity, message; - switch (newState) { - case states.connecting: - message = "Connecting..."; - timeout = 0; - severity = severities.warning; - break; - case states.connected: - window.onbeforeunload = windowUnload; - message = "Connected"; - break; - case states.disconnecting: - window.onbeforeunload = undefined; - message = "Disconnecting..."; - timeout = 0; - severity = severities.warning; - break; - case states.reconnecting: - window.onbeforeunload = undefined; - message = "Reconnecting..."; - timeout = 0; - severity = severities.warning; - break; - case states.disconnected: - window.onbeforeunload = undefined; - switch (state) { - case states.start: - case states.connecting: - case states.reconnecting: - message = "Connection failed"; - timeout = 0; - severity = severities.error; - break; - case states.connected: - case states.disconnecting: - var time_since_started = new Date() - starttime; - timeout = 5000; - if (time_since_started > 5*1000 || type === 'shell') { - message = "Connection closed"; - } else { - message = "Connection failed"; - severity = severities.error; - } - break; - case states.disconnected: - // no state change - break; - default: - throw "unknown state"; - } - break; - default: - throw "unknown state"; - } - let msgArr = []; - if (msg) { - msgArr.push(msg); - } - if (code !== undefined) { - msgArr.push(`Code: ${code}`); - } - if (msgArr.length > 0) { - message += ` (${msgArr.join(', ')})`; - } - state = newState; - showMsg(message, timeout, severity); -} - -var terminalContainer = document.getElementById('terminal-container'); -document.getElementById('status_bar').addEventListener('click', hideMsg); -document.getElementById('connect_btn').addEventListener('click', startGuest); -const fitAddon = new FitAddon.FitAddon(); -const webglAddon = new WebglAddon.WebglAddon(); - -createTerminal(); - -function startConnection(url, params, term) { - API2Request({ - method: 'POST', - params: params, - url: url + '/termproxy', - success: function(result) { - var port = encodeURIComponent(result.data.port); - ticket = result.data.ticket; - socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/api2/json' + url + '/vncwebsocket?port=' + port + '&vncticket=' + encodeURIComponent(ticket); - - socket = new WebSocket(socketURL, 'binary'); - socket.binaryType = 'arraybuffer'; - socket.onopen = runTerminal; - socket.onclose = tryReconnect; - socket.onerror = tryReconnect; - updateState(states.connecting); - }, - failure: function(msg) { - updateState(states.disconnected,msg); - } - }); -} - -function startGuest() { - let api_type = type === 'kvm' ? 'qemu' : 'lxc'; - API2Request({ - method: 'POST', - url: `/nodes/${nodename}/${api_type}/${vmid}/status/start`, - success: function(result) { - showMsg('Guest started successfully', 0); - setTimeout(function() { - location.reload(); - }, 1000); - }, - failure: function(msg) { - if (msg.match(/already running/)) { - showMsg('Guest started successfully', 0); - setTimeout(function() { - location.reload(); - }, 1000); - } else { - updateState(states.disconnected,msg); - } - } - }); -} - -function createTerminal() { - term = new Terminal(getTerminalSettings()); - term.open(terminalContainer); - term.loadAddon(fitAddon); - try { - term.loadAddon(webglAddon); - } catch (_e) { - console.warn("webgl-addon loading failed, falling back to regular dom renderer"); - } - - term.onResize(function (size) { - if (state === states.connected) { - socket.send("1:" + size.cols + ":" + size.rows + ":"); - } - }); - - protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'; - - var params = {}; - var url = '/nodes/' + nodename; - switch (type) { - case 'kvm': - url += '/qemu/' + vmid; - break; - case 'lxc': - url += '/lxc/' + vmid; - break; - case 'upgrade': - params.cmd = 'upgrade'; - break; - case 'cmd': - params.cmd = decodeURI(cmd); - if (cmdOpts !== undefined && cmdOpts !== null && cmdOpts !== "") { - params['cmd-opts'] = decodeURI(cmdOpts); - } - break; - } - if (type === 'kvm' || type === 'lxc') { - API2Request({ - method: 'GET', - url: `${url}/status/current`, - success: function(result) { - if (result.data.status === 'running') { - startConnection(url, params, term); - } else { - document.getElementById('connect_dlg').classList.add('pve_open'); - } - }, - failure: function(msg) { - updateState(states.disconnected, msg); - }, - }); - } else { - startConnection(url, params, term); - } -} - -function runTerminal() { - socket.onmessage = function(event) { - var answer = new Uint8Array(event.data); - if (state === states.connected) { - term.write(answer); - } else if(state === states.connecting) { - if (answer[0] === 79 && answer[1] === 75) { // "OK" - updateState(states.connected); - term.write(answer.slice(2)); - } else { - socket.close(); - } - } - }; - - term.onData(function(data) { - if (state === states.connected) { - socket.send("0:" + unescape(encodeURIComponent(data)).length.toString() + ":" + data); - } - }); - - ping = setInterval(function() { - socket.send("2"); - }, 30*1000); - - window.addEventListener('resize', function() { - clearTimeout(resize); - resize = setTimeout(function() { - // done resizing - fitAddon.fit(); - }, 250); - }); - - socket.send(PVE.UserName + ':' + ticket + "\n"); - - // initial focus and resize - setTimeout(function() { - term.focus(); - fitAddon.fit(); - }, 250); -} - -function getLxcStatus(callback) { - API2Request({ - method: 'GET', - url: '/nodes/' + nodename + '/lxc/' + vmid + '/status/current', - success: function(result) { - if (typeof callback === 'function') { - callback(true, result); - } - }, - failure: function(msg) { - if (typeof callback === 'function') { - callback(false, msg); - } - } - }); -} - -function checkMigration() { - var apitype = type; - if (apitype === 'kvm') { - apitype = 'qemu'; - } - API2Request({ - method: 'GET', - params: { - type: 'vm' - }, - url: '/cluster/resources', - success: function(result) { - // if not yet migrated , wait and try again - // if not migrating and stopped, cancel - // if started, connect - result.data.forEach(function(entity) { - if (entity.id === (apitype + '/' + vmid)) { - var started = entity.status === 'running'; - var migrated = entity.node !== nodename; - if (migrated) { - if (started) { - // goto different node - location.href = '?console=' + type + - '&xtermjs=1&vmid=' + vmid + '&vmname=' + - vmname + '&node=' + entity.node; - } else { - // wait again - updateState(states.reconnecting, 'waiting for migration to finish...'); - setTimeout(checkMigration, 5000); - } - } else { - if (type === 'lxc') { - // we have to check the status of the - // container to know if it has the - // migration lock - getLxcStatus(function(success, result) { - if (success) { - if (result.data.lock === 'migrate') { - // still waiting - updateState(states.reconnecting, 'waiting for migration to finish...'); - setTimeout(checkMigration, 5000); - } else if (started) { - // container was rebooted - location.reload(); - } else { - stopTerminal(); - } - } else { - // probably the status call failed because - // the ct is already somewhere else, so retry - setTimeout(checkMigration, 1000); - } - }); - } else if (started) { - // this happens if we have old data in - // /cluster/resources, or the connection - // disconnected, so simply try to reload here - location.reload(); - } else if (type === 'kvm') { - // it seems the guest simply stopped - stopTerminal(); - } - } - - return; - } - }); - }, - failure: function(msg) { - errorTerminal({msg: msg}); - } - }); -} - -function tryReconnect(event) { - var time_since_started = new Date() - starttime; - var type = getQueryParameter('console'); - if (time_since_started < 5*1000 || type === 'shell' || type === 'cmd') { // 5 seconds - stopTerminal(event); - return; - } - - updateState(states.disconnecting, 'Detecting migration...'); - setTimeout(checkMigration, 5000); -} - -function clearEvents() { - term.onResize(() => {}); - term.onData(() => {}); -} - -function windowUnload(e) { - let message = "Are you sure you want to leave this page?"; - - e = e || window.event; - if (e) { - e.returnValue = message; - } - - return message; -} - -function stopTerminal(event) { - event = event || {}; - clearEvents(); - clearInterval(ping); - socket.close(); - updateState(states.disconnected, event.reason, event.code); -} - -function errorTerminal(event) { - event = event || {}; - clearEvents(); - clearInterval(ping); - socket.close(); - term.dispose(); - updateState(states.disconnected, event.msg, event.code); -}