From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <d.csapak@proxmox.com> Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id BEFA9637A2 for <pve-devel@lists.proxmox.com>; Fri, 25 Feb 2022 15:10:51 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id A47DB229D7 for <pve-devel@lists.proxmox.com>; Fri, 25 Feb 2022 15:10:21 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 1F3A7229C8 for <pve-devel@lists.proxmox.com>; Fri, 25 Feb 2022 15:10:20 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id D926546E21 for <pve-devel@lists.proxmox.com>; Fri, 25 Feb 2022 15:10:19 +0100 (CET) From: Dominik Csapak <d.csapak@proxmox.com> To: pve-devel@lists.proxmox.com Date: Fri, 25 Feb 2022 15:10:18 +0100 Message-Id: <20220225141018.1613511-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.156 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pve-devel] [PATCH xtermjs] detect not running guests and add start button X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion <pve-devel.lists.proxmox.com> List-Unsubscribe: <https://lists.proxmox.com/cgi-bin/mailman/options/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=unsubscribe> List-Archive: <http://lists.proxmox.com/pipermail/pve-devel/> List-Post: <mailto:pve-devel@lists.proxmox.com> List-Help: <mailto:pve-devel-request@lists.proxmox.com?subject=help> List-Subscribe: <https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel>, <mailto:pve-devel-request@lists.proxmox.com?subject=subscribe> X-List-Received-Date: Fri, 25 Feb 2022 14:10:51 -0000 akin to what we now have in novnc css classes copied from novnc, so that we have the same look Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- src/www/index.html.hbs.in | 6 +++ src/www/index.html.tpl.in | 6 +++ src/www/main.js | 89 +++++++++++++++++++++++++++++---------- src/www/style.css | 59 ++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 22 deletions(-) diff --git a/src/www/index.html.hbs.in b/src/www/index.html.hbs.in index 0dba066..0520340 100644 --- a/src/www/index.html.hbs.in +++ b/src/www/index.html.hbs.in @@ -11,6 +11,12 @@ <body> <div id="status_bar"></div> <div id="wrap"> + <div class="center"> + <div id="connect_dlg"> + <div id="pve_start_info">Guest not running</div> + <div id="connect_btn"><div> Start Now </div></div> + </div> + </div> <div id="terminal-container"></div> </div> <script type="text/javascript"> diff --git a/src/www/index.html.tpl.in b/src/www/index.html.tpl.in index 5002035..f38e0b2 100644 --- a/src/www/index.html.tpl.in +++ b/src/www/index.html.tpl.in @@ -11,6 +11,12 @@ <body> <div id="status_bar"></div> <div id="wrap"> + <div class="center"> + <div id="connect_dlg"> + <div id="pve_start_info">Guest not running</div> + <div id="connect_btn"><div> Start Now </div></div> + </div> + </div> <div id="terminal-container"></div> </div> <script type="text/javascript"> diff --git a/src/www/main.js b/src/www/main.js index c2811f6..2c81e7f 100644 --- a/src/www/main.js +++ b/src/www/main.js @@ -97,10 +97,59 @@ function updateState(newState, msg, code) { 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(); 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); + + term.open(terminalContainer, true); + 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.loadAddon(fitAddon); @@ -132,28 +181,24 @@ function createTerminal() { } break; } - 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); - - term.open(terminalContainer, true); - 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); - } - }); - + 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() { diff --git a/src/www/style.css b/src/www/style.css index 20959c0..04db7d5 100644 --- a/src/www/style.css +++ b/src/www/style.css @@ -83,3 +83,62 @@ html,body { #status_bar.warning { background: rgba(180,180,30,0.9); } + +#pve_start_info { + color: white; + text-align: center; + font-size: 20px; + padding: 6px; +} + +#connect_dlg { + transition: 0.2s ease-in-out; + + transform: scale(0, 0); + visibility: hidden; + opacity: 0; + font-family: Helvetica; +} + +#connect_dlg.pve_open { + transform: scale(1, 1); + visibility: visible; + opacity: 1; +} + +#connect_btn { + cursor: pointer; + padding: 6px; + color: white; + background:#4c4c4c;; + border-radius: 8px; + text-align: center; + font-size: 20px; + box-shadow: 4px 4px 0px rgba(0, 0, 0, 0.5); +} +#connect_btn div { + margin: 2px; + padding: 5px 30px; + border: 1px solid #2f2f2f; + border-bottom-width: 2px; + border-radius: 5px; + background:#4c4c4c;; + + /* This avoids it jumping around when :active */ + vertical-align: middle; +} +#connect_btn div:active { + border-bottom-width: 1px; + margin-top: 3px; +} + +div.center { + display: flex; + align-items: center; + justify-content: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; +} -- 2.30.2