[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