[ARVADOS] created: 1.3.0-3028-g83d9f52a8
Git user
git at public.arvados.org
Fri Aug 28 19:27:05 UTC 2020
at 83d9f52a85cd19e9821d54b3d6ec9efdff337777 (commit)
commit 83d9f52a85cd19e9821d54b3d6ec9efdff337777
Author: Peter Amstutz <peter.amstutz at curii.com>
Date: Fri Aug 28 15:19:57 2020 -0400
16773: Fix webshell wait for prompt & asset loading
Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <peter.amstutz at curii.com>
diff --git a/apps/workbench/app/views/virtual_machines/webshell.html.erb b/apps/workbench/app/views/virtual_machines/webshell.html.erb
index 4c63115a1..89c7c2bb8 100644
--- a/apps/workbench/app/views/virtual_machines/webshell.html.erb
+++ b/apps/workbench/app/views/virtual_machines/webshell.html.erb
@@ -30,17 +30,43 @@ SPDX-License-Identifier: AGPL-3.0 %>
function login(username, token) {
var sh = new ShellInABox("<%= j @webshell_url %>");
- setTimeout(function() {
- sh.keysPressed("<%= j params[:login] %>\n");
- setTimeout(function() {
- sh.keysPressed("<%= j Thread.current[:arvados_api_token] %>\n");
- sh.vt100('(sent authentication token)\n');
- }, 2000);
- }, 2000);
+
+ var findText = function(txt) {
+ var a = document.querySelectorAll("span.ansi0");
+ for (var i = 0; i < a.length; i++) {
+ if (a[i].textContent.indexOf(txt) > -1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ var trySendToken = function() {
+ // change this text when PAM is reconfigured to present a
+ // password prompt that we can wait for.
+ if (findText("login:")) {
+ sh.keysPressed("<%= j Thread.current[:arvados_api_token] %>\n");
+ sh.vt100('(sent authentication token)\n');
+ } else {
+ setTimeout(trySendToken, 200);
+ }
+ };
+
+ var trySendLogin = function() {
+ if (findText("login:")) {
+ sh.keysPressed("<%= j params[:login] %>\n");
+ // Make this wait shorter when PAM is reconfigured to
+ // present a password prompt that we can wait for.
+ setTimeout(trySendToken, 3000);
+ } else {
+ setTimeout(trySendLogin, 200);
+ }
+ };
+
+ trySendLogin();
}
// -->
</script>
- <link rel="icon" href="<%= asset_path 'favicon.ico' %>" type="image/x-icon">
<script type="text/javascript" src="<%= asset_path 'webshell/shell_in_a_box.js' %>"></script>
</head>
<!-- Load ShellInABox from a timer as Konqueror sometimes fails to
diff --git a/apps/workbench/config/initializers/assets.rb b/apps/workbench/config/initializers/assets.rb
index f02c87b73..2cb9ae908 100644
--- a/apps/workbench/config/initializers/assets.rb
+++ b/apps/workbench/config/initializers/assets.rb
@@ -12,4 +12,4 @@ Rails.application.config.assets.version = '1.0'
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
-# Rails.application.config.assets.precompile += %w( search.js )
+Rails.application.config.assets.precompile += %w( webshell/styles.css webshell/shell_in_a_box.js )
diff --git a/apps/workbench/public/webshell/shell_in_a_box.js b/apps/workbench/lib/assets/javascripts/webshell/shell_in_a_box.js
similarity index 99%
rename from apps/workbench/public/webshell/shell_in_a_box.js
rename to apps/workbench/lib/assets/javascripts/webshell/shell_in_a_box.js
index 0c7e800ef..1002f7a9f 100644
--- a/apps/workbench/public/webshell/shell_in_a_box.js
+++ b/apps/workbench/lib/assets/javascripts/webshell/shell_in_a_box.js
@@ -1,3 +1,7 @@
+// Copyright (C) 2008-2010 Markus Gutschke <markus at shellinabox.com> All rights reserved.
+//
+// SPDX-License-Identifier: GPL-2.0
+
// This file contains code from shell_in_a_box.js and vt100.js
@@ -363,7 +367,7 @@ ShellInABox.prototype.extendContextMenu = function(entries, actions) {
}
}
}
-
+
};
ShellInABox.prototype.about = function() {
@@ -738,7 +742,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
var label = userCSSList[i][0];
var newGroup = userCSSList[i][1];
var enabled = userCSSList[i][2];
-
+
// Add user style sheet to document
var style = document.createElement('link');
var id = document.createAttribute('id');
@@ -756,7 +760,7 @@ VT100.prototype.initializeUserCSSStyles = function() {
document.getElementsByTagName('head')[0].appendChild(style);
style.disabled = !enabled;
}
-
+
// Add entry to menu
if (newGroup || i == userCSSList.length) {
if (beginOfGroup != 0 && (i - beginOfGroup > 1 || !wasSingleSel)) {
@@ -963,7 +967,7 @@ VT100.prototype.addKeyBinding = function(elem, ch, key, CH, KEY) {
this.addListener(elem, 'mousedown',
function(vt100, elem, key) { return function(e) {
if ((e.which || e.button) == 1) {
- if (vt100.lastSelectedKey) {
+ if (vt100.lastSelectedKey) {
vt100.lastSelectedKey.className= '';
}
// Highlight the key while the mouse button is held down.
@@ -1364,7 +1368,7 @@ VT100.prototype.initializeElements = function(container) {
vt100.indicateSize = true;
};
}(this), 100);
- this.addListener(window, 'resize',
+ this.addListener(window, 'resize',
function(vt100) {
return function() {
vt100.hideContextMenu();
@@ -1372,7 +1376,7 @@ VT100.prototype.initializeElements = function(container) {
vt100.showCurrentSize();
}
}(this));
-
+
// Hide extra scrollbars attached to window
document.body.style.margin = '0px';
try { document.body.style.overflow ='hidden'; } catch (e) { }
@@ -1447,7 +1451,7 @@ VT100.prototype.initializeElements = function(container) {
// Add a listener for the drop event
this.addListener(this.scrollable, 'drop', dropEvent(this));
}
-
+
// Initialize the blank terminal window.
this.currentScreen = 0;
this.cursorX = 0;
@@ -1514,7 +1518,7 @@ VT100.prototype.repairElements = function(console) {
for (var span = line.firstChild; span; span = span.nextSibling) {
var newSpan = document.createElement(span.tagName);
newSpan.style.cssText = span.style.cssText;
- newSpan.className = span.className;
+ newSpan.className = span.className;
this.setTextContent(newSpan, this.getTextContent(span));
newLine.appendChild(newSpan);
}
@@ -1925,7 +1929,7 @@ VT100.prototype.insertBlankLine = function(y, color, style) {
line = document.createElement('div');
var span = document.createElement('span');
span.style.cssText = style;
- span.className = color;
+ span.className = color;
this.setTextContent(span, this.spaces(this.terminalWidth));
line.appendChild(span);
}
@@ -2062,7 +2066,7 @@ VT100.prototype.putString = function(x, y, text, color, style) {
this.insertBlankLine(yIdx);
}
line = console.childNodes[yIdx];
-
+
// If necessary, promote blank '\n' line to a <div> tag
if (line.tagName != 'DIV') {
var div = document.createElement('div');
@@ -2106,7 +2110,7 @@ VT100.prototype.putString = function(x, y, text, color, style) {
s += ' ';
} while (xPos + s.length < x);
}
-
+
// If styles do not match, create a new <span>
var del = text.length - s.length + x - xPos;
if (oldColor != color ||
@@ -2165,7 +2169,7 @@ VT100.prototype.putString = function(x, y, text, color, style) {
}
this.setTextContent(span, s);
-
+
// Delete all subsequent <span>'s that have just been overwritten
sibling = span.nextSibling;
while (del > 0 && sibling) {
@@ -2180,7 +2184,7 @@ VT100.prototype.putString = function(x, y, text, color, style) {
break;
}
}
-
+
// Merge <span> with next sibling, if styles are identical
if (sibling && span.className == sibling.className &&
span.style.cssText == sibling.style.cssText) {
@@ -2261,7 +2265,7 @@ VT100.prototype.putString = function(x, y, text, color, style) {
this.getTextContent(span));
line.removeChild(sibling);
}
-
+
// Prune white space from the end of the current line
span = line.lastChild;
while (span &&
@@ -2342,7 +2346,7 @@ VT100.prototype.enableAlternateScreen = function(state) {
this.resizer();
return;
}
-
+
// We save the full state of the normal screen, when we switch away from it.
// But for the alternate screen, no saving is necessary. We always reset
// it when we switch to it.
@@ -2588,7 +2592,7 @@ VT100.prototype.scrollRegion = function(x, y, w, h, incX, incY,
while (console.childNodes.length < this.terminalHeight) {
this.insertBlankLine(this.terminalHeight);
}
-
+
// Add new lines at bottom in order to force scrolling
for (var i = 0; i < y; i++) {
this.insertBlankLine(console.childNodes.length, color, style);
@@ -2947,7 +2951,7 @@ VT100.prototype.showContextMenu = function(x, y) {
this.menu.style.height = this.container.offsetHeight + 'px';
popup.style.left = '0px';
popup.style.top = '0px';
-
+
var margin = 2;
if (x + popup.clientWidth >= this.container.offsetWidth - margin) {
x = this.container.offsetWidth-popup.clientWidth - margin - 1;
@@ -3035,7 +3039,7 @@ VT100.prototype.handleKey = function(event) {
ch = this.applyModifiers(ch, event);
// By this point, "ch" is either defined and contains the character code, or
- // it is undefined and "key" defines the code of a function key
+ // it is undefined and "key" defines the code of a function key
if (ch != undefined) {
this.scrollable.scrollTop = this.numScrollbackLines *
this.cursorHeight + 1;
@@ -3260,7 +3264,7 @@ VT100.prototype.fixEvent = function(event) {
case 61: /* = -> + */ u = 61; s = 43; break;
case 91: /* [ -> { */ u = 91; s = 123; break;
case 92: /* \ -> | */ u = 92; s = 124; break;
- case 93: /* ] -> } */ u = 93; s = 125; break;
+ case 93: /* ] -> } */ u = 93; s = 125; break;
case 96: /* ` -> ~ */ u = 96; s = 126; break;
case 109: /* - -> _ */ u = 45; s = 95; break;
@@ -3276,7 +3280,7 @@ VT100.prototype.fixEvent = function(event) {
case 192: /* ` -> ~ */ u = 96; s = 126; break;
case 219: /* [ -> { */ u = 91; s = 123; break;
case 220: /* \ -> | */ u = 92; s = 124; break;
- case 221: /* ] -> } */ u = 93; s = 125; break;
+ case 221: /* ] -> } */ u = 93; s = 125; break;
case 222: /* ' -> " */ u = 39; s = 34; break;
default: break;
}
@@ -3989,7 +3993,7 @@ VT100.prototype.sendControlToPrinter = function(ch) {
break;
}
// Fall through
- case 3 /* ESgetpars */:
+ case 3 /* ESgetpars */:
if (ch == 0x3B /*;*/) {
this.npar++;
break;
@@ -4351,7 +4355,7 @@ VT100.prototype.doControl = function(ch) {
}
// Fall through
case 5 /* ESdeviceattr */:
- case 3 /* ESgetpars */:
+ case 3 /* ESgetpars */:
/*;*/ if (ch == 0x3B) {
this.npar++;
break;
@@ -4626,7 +4630,7 @@ VT100.prototype.vt100 = function(s) {
this.utfEnabled && ch >= 128 ||
!(this.dispCtrl ? this.ctrlAlways : this.ctrlAction)[ch & 0x1F]) &&
(ch != 0x7F || this.dispCtrl);
-
+
if (isNormalCharacter && this.isEsc == 0 /* ESnormal */) {
if (ch < 256) {
ch = this.translate[this.toggleMeta ? (ch | 0x80) : ch];
@@ -4831,5 +4835,3 @@ VT100.prototype.ctrlAlways = [
false, false, false, false, false, false, false, false,
false, false, false, true, false, false, false, false
];
-
-
diff --git a/apps/workbench/public/webshell/styles.css b/apps/workbench/lib/assets/stylesheets/webshell/styles.css
similarity index 93%
rename from apps/workbench/public/webshell/styles.css
rename to apps/workbench/lib/assets/stylesheets/webshell/styles.css
index 3097cb45b..1fc8a6704 100644
--- a/apps/workbench/public/webshell/styles.css
+++ b/apps/workbench/lib/assets/stylesheets/webshell/styles.css
@@ -1,9 +1,13 @@
-#vt100 a {
+/* Copyright (C) 2008-2010 Markus Gutschke <markus at shellinabox.com> All rights reserved.
+ SPDX-License-Identifier: GPL-2.0
+*/
+
+#vt100 a {
text-decoration: none;
color: inherit;
}
-#vt100 a:hover {
+#vt100 a:hover {
text-decoration: underline;
}
@@ -12,7 +16,7 @@
z-index: 2;
}
-#vt100 #reconnect input {
+#vt100 #reconnect input {
padding: 1ex;
font-weight: bold;
font-size: x-large;
@@ -29,7 +33,7 @@
z-index: 2;
}
-#vt100 pre {
+#vt100 pre {
margin: 0px;
}
@@ -44,11 +48,11 @@
padding: 1px;
}
-#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre {
+#vt100 #console, #vt100 #alt_console, #vt100 #cursor, #vt100 #lineheight, #vt100 .hidden pre {
font-family: "DejaVu Sans Mono", "Everson Mono", FreeMono, "Andale Mono", monospace;
}
-#vt100 #lineheight {
+#vt100 #lineheight {
position: absolute;
visibility: hidden;
}
@@ -75,7 +79,7 @@
margin: -1px;
}
-#vt100 #padding {
+#vt100 #padding {
visibility: hidden;
width: 1px;
height: 0px;
@@ -90,7 +94,7 @@
height: 0px;
}
-#vt100 #menu {
+#vt100 #menu {
overflow: visible;
position: absolute;
z-index: 3;
@@ -103,14 +107,14 @@
position: absolute;
}
-#vt100 #menu .popup ul {
+#vt100 #menu .popup ul {
list-style-type: none;
padding: 0px;
margin: 0px;
min-width: 10em;
}
-#vt100 #menu .popup li {
+#vt100 #menu .popup li {
padding: 3px 0.5ex 3px 0.5ex;
}
@@ -123,11 +127,11 @@
color: #AAAAAA;
}
-#vt100 #menu .popup hr {
+#vt100 #menu .popup hr {
margin: 0.5ex 0px 0.5ex 0px;
}
-#vt100 #menu img {
+#vt100 #menu img {
margin-right: 0.5ex;
width: 1ex;
height: 1ex;
@@ -136,7 +140,7 @@
#vt100 #scrollable.inverted { color: #ffffff;
background-color: #000000; }
-#vt100 #kbd_button {
+#vt100 #kbd_button {
float: left;
position: fixed;
z-index: 0;
@@ -198,7 +202,7 @@
visibility: hidden;
}
-#vt100 #keyboard .shifted {
+#vt100 #keyboard .shifted {
display: none;
}
@@ -257,15 +261,15 @@
display: none;
}
- #vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard {
+ #vt100 #reconnect, #vt100 #cursor, #vt100 #menu, #vt100 #kbd_button, #vt100 #keyboard {
visibility: hidden;
}
- #vt100 #scrollable {
+ #vt100 #scrollable {
overflow: hidden;
}
- #vt100 #console, #vt100 #alt_console {
+ #vt100 #console, #vt100 #alt_console {
overflow: hidden;
width: 1000000ex;
}
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list