diff --git a/client/galaxy/scripts/bundleEntries.js b/client/galaxy/scripts/bundleEntries.js index 7b44c5245af..abc8be4d625 100644 --- a/client/galaxy/scripts/bundleEntries.js +++ b/client/galaxy/scripts/bundleEntries.js @@ -32,6 +32,9 @@ export { default as HDAModel } from "mvc/history/hda-model"; export { default as LegacyGridView } from "legacy/grid/grid-view"; export { create_chart, create_histogram } from "reports/run_stats"; export { default as ToolshedGroups } from "toolshed/toolshed.groups"; +export { default as IES } from "galaxy.interactive_environments"; + +export { Toast } from "ui/toast"; // TODO: remove when external consumers are updated/gone (IES right now) export function adminToolshed(options) { new AdminToolshed.GalaxyApp(options); diff --git a/client/galaxy/scripts/galaxy.interactive_environments.js b/client/galaxy/scripts/galaxy.interactive_environments.js index 6ae025c5bb7..c1d3b3509b9 100644 --- a/client/galaxy/scripts/galaxy.interactive_environments.js +++ b/client/galaxy/scripts/galaxy.interactive_environments.js @@ -1,6 +1,6 @@ -/* global $ */ -/* global toastr */ -// TODO: this file is transpiled and used directly without bundling; fix imports when that is no longer the case. +import $ from "jquery"; +import { Toast } from "ui/toast"; + /** * Internal function to remove content from the main area and add the notebook. * Not idempotent @@ -35,7 +35,7 @@ export function make_spin_state( sleep_step, log_attempts ) { - var s = { + return { type: typeof type !== "undefined" ? type : "GIE spin", ajax_timeout: typeof ajax_timeout_init !== "undefined" ? ajax_timeout_init : 2000, ajax_timeout_max: typeof ajax_timeout_max !== "undefined" ? ajax_timeout_max : 16000, @@ -46,7 +46,6 @@ export function make_spin_state( log_attempts: typeof log_attempts !== "undefined" ? log_attempts : true, count: 0 }; - return s; } /* Log/display an error when spinning fails. */ @@ -54,8 +53,8 @@ export function spin_error(console_msg, user_msg, clear) { console.log(console_msg); if (clear) clear_main_area(); if (typeof user_msg == "string") { - toastr.clear(); - toastr.error(user_msg, "Error", { + Toast.clear(); + Toast.error(user_msg, "Error", { closeButton: true, timeOut: 0, extendedTimeOut: 0, @@ -112,7 +111,7 @@ export function spin(url, bool_response, success_callback, timeout_callback, err } } }; - if (bool_response) ajax_params["dataType"] = "json"; + if (bool_response) ajax_params.dataType = "json"; $.ajax(ajax_params); }; console.log(`Setting up new spinner for ${spin_state.type} on ${url}`); @@ -131,7 +130,7 @@ function spin_until(url, bool_response, messages, success_callback, spin_state) var message_once = (message, spin_state) => { if (spin_state.count == 1) { display_spinner(); - toastr.info(message, null, { + Toast.info(message, null, { closeButton: true, timeOut: 0, extendedTimeOut: 0, @@ -141,22 +140,22 @@ function spin_until(url, bool_response, messages, success_callback, spin_state) }; var wrapped_success = data => { if (!bool_response || (bool_response && data == true)) { - console.log(messages["success"]); + console.log(messages.success); clear_main_area(); - toastr.clear(); + Toast.clear(); success_callback(); } else if (bool_response && data == false) { - message_once(messages["not_ready"], spin_state); + message_once(messages.not_ready, spin_state); return false; // keep spinning } else { - spin_error(`Invalid response to ${spin_state.type} request`, messages["invalid_response"], true); + spin_error(`Invalid response to ${spin_state.type} request`, messages.invalid_response, true); } return true; // stop spinning }; var timeout_error = (jqxhr, status, error) => { - message_once(messages["waiting"], spin_state); + message_once(messages.waiting, spin_state); if (spin_state.count == warn_at) { - toastr.warning(messages["wait_warn"], "Warning", { + Toast.warning(messages.wait_warn, "Warning", { closeButton: true, timeOut: 0, extendedTimeOut: 0, @@ -235,7 +234,7 @@ export function keepAlive(notebookAccessURL) { if (request_count > 30) { window.clearInterval(interval); clear_main_area(); - toastr.error("Could not connect to IE, contact your administrator", "Error", { + Toast.error("Could not connect to IE, contact your administrator", "Error", { closeButton: true, timeOut: 20000, tapToDismiss: false @@ -245,3 +244,15 @@ export function keepAlive(notebookAccessURL) { }); }, 10000); } + +export default { + append_notebook, + clear_main_area, + display_spinner, + make_spin_state, + spin_error, + spin, + test_ie_availability, + load_when_ready, + keepAlive +}; \ No newline at end of file diff --git a/config/galaxy.yml.sample b/config/galaxy.yml.sample index c911ebe358f..3d33fff38da 100644 --- a/config/galaxy.yml.sample +++ b/config/galaxy.yml.sample @@ -144,7 +144,7 @@ galaxy: # than 5 milliseconds. #slow_query_log_threshold: 0 - # Enable's a per request sql debugging option. If this is set to true, + # Enables a per request sql debugging option. If this is set to true, # append ?sql_debug=1 to web request URLs to enable detailed logging # on the backend of SQL queries generated during that request. This is # useful for debugging slow endpoints during development. @@ -333,7 +333,7 @@ galaxy: # be used for job destinations with Docker enabled. #enable_beta_mulled_containers: false - # Container resolvers configuration (beta). Setup a file describing + # Container resolvers configuration (beta). Set up a file describing # container resolvers to use when discovering containers for Galaxy. # If this is set to None, the default containers loaded is determined # by enable_beta_mulled_containers. @@ -632,7 +632,7 @@ galaxy: # Galaxy can display data at various external browsers. These options # specify which browsers should be available. URLs and builds - # available at these browsers are defined in the specifield files. If + # available at these browsers are defined in the specified files. If # use_remote_user = True, display application servers will be denied # access to Galaxy and so displaying datasets in these sites will # fail. display_servers contains a list of hostnames which should be @@ -693,11 +693,10 @@ galaxy: # URL (with schema http/https) of the Galaxy instance as accessible # within your local network - if specified used as a default by pulsar # file staging and Jupyter Docker container for communicating back - # with Galaxy via the API. If you are attempting to setup GIEs on Mac - # OS X with Docker for Mac - this should likely be the IP address of - # your machine on the virtualbox network (vboxnet0) setup for the - # Docker host VM. This can found by running ifconfig and using the IP - # address of the network vboxnet0. + # with Galaxy via the API. If you are attempting to set up GIEs on + # Mac OS X with Docker Desktop for Mac and your Galaxy instance runs + # on port 8080 this should be 'http://host.docker.internal:8080'. For + # more details see https://docs.docker.com/docker-for-mac/networking/ #galaxy_infrastructure_url: http://localhost:8080 # If the above URL cannot be determined ahead of time in dynamic @@ -877,11 +876,11 @@ galaxy: # for IPC, set that here. #dynamic_proxy_session_map: database/session_map.sqlite - # Set the port and IP for the the dynamic proxy to bind to, this must + # Set the port and IP for the dynamic proxy to bind to, this must # match the external configuration if dynamic_proxy_manage is False. #dynamic_proxy_bind_port: 8800 - # Set the port and IP for the the dynamic proxy to bind to, this must + # Set the port and IP for the dynamic proxy to bind to, this must # match the external configuration if dynamic_proxy_manage is False. #dynamic_proxy_bind_ip: 0.0.0.0 diff --git a/config/plugins/interactive_environments/askomics/static/js/askomics.js b/config/plugins/interactive_environments/askomics/static/js/askomics.js deleted file mode 100644 index ad674394807..00000000000 --- a/config/plugins/interactive_environments/askomics/static/js/askomics.js +++ /dev/null @@ -1,9 +0,0 @@ -var IES = window.IES; - -function load_askomics(url){ - $( document ).ready(function() { - IES.test_ie_availability(url, function(){ - IES.append_notebook(url); - }); - }); -} diff --git a/config/plugins/interactive_environments/askomics/static/js/main.js b/config/plugins/interactive_environments/askomics/static/js/main.js new file mode 100644 index 00000000000..791dac16749 --- /dev/null +++ b/config/plugins/interactive_environments/askomics/static/js/main.js @@ -0,0 +1,9 @@ +var IES = window.IES; + +function load_askomics(url) { + $(document).ready(function() { + IES.test_ie_availability(url, function() { + IES.append_notebook(url); + }); + }); +} diff --git a/config/plugins/interactive_environments/askomics/templates/askomics.mako b/config/plugins/interactive_environments/askomics/templates/askomics.mako index 29195f1baf5..e9dfb8441da 100644 --- a/config/plugins/interactive_environments/askomics/templates/askomics.mako +++ b/config/plugins/interactive_environments/askomics/templates/askomics.mako @@ -34,16 +34,13 @@ url = ie_request.url_template('${PROXY_URL}/login_api_gie?key=' + askomics_api_k ${ ie.load_default_js() } +${ ie.load_default_app() }
diff --git a/config/plugins/interactive_environments/bam_iobio/static/js/bam_iobio.js b/config/plugins/interactive_environments/bam_iobio/static/js/main.js similarity index 53% rename from config/plugins/interactive_environments/bam_iobio/static/js/bam_iobio.js rename to config/plugins/interactive_environments/bam_iobio/static/js/main.js index d706be38d26..b9e69702abf 100644 --- a/config/plugins/interactive_environments/bam_iobio/static/js/bam_iobio.js +++ b/config/plugins/interactive_environments/bam_iobio/static/js/main.js @@ -2,20 +2,20 @@ var IES = window.IES; var toastr = window.toastr; -function message_failed_auth(password){ - toastr.info( - "Automatic authorization failed.", - "Please login manually", - {'closeButton': true, 'timeOut': 100000, 'tapToDismiss': false} - ); +function message_failed_auth(password) { + toastr.info("Automatic authorization failed.", "Please login manually", { + closeButton: true, + timeOut: 100000, + tapToDismiss: false + }); } -function message_failed_connection(){ - toastr.error( - "Could not connect to BAM iobio. Please contact your administrator.", - "Security warning", - {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': true} - ); +function message_failed_connection() { + toastr.error("Could not connect to BAM iobio. Please contact your administrator.", "Security warning", { + closeButton: true, + timeOut: 20000, + tapToDismiss: true + }); } /** @@ -25,10 +25,10 @@ function message_failed_connection(){ * @param {String} notebook_access_url: the URL embeded in the page and loaded * */ -function load_notebook(notebook_access_url){ +function load_notebook(notebook_access_url) { // Test notebook_login_url for accessibility, executing the login+load function whenever // we've successfully connected to the IE. - IES.test_ie_availability(notebook_access_url, function(){ + IES.test_ie_availability(notebook_access_url, function() { _handle_notebook_loading(notebook_access_url); }); } @@ -36,6 +36,6 @@ function load_notebook(notebook_access_url){ /** * Must be implemented by IEs */ -function _handle_notebook_loading(notebook_access_url){ +function _handle_notebook_loading(notebook_access_url) { IES.append_notebook(notebook_access_url); } diff --git a/config/plugins/interactive_environments/bam_iobio/templates/bam_iobio.mako b/config/plugins/interactive_environments/bam_iobio/templates/bam_iobio.mako index 16115b2847a..4060fa9ff6a 100644 --- a/config/plugins/interactive_environments/bam_iobio/templates/bam_iobio.mako +++ b/config/plugins/interactive_environments/bam_iobio/templates/bam_iobio.mako @@ -24,6 +24,7 @@ root = h.url_for( '/' ) ${ ie.load_default_js() } + ${ ie.load_default_app() } @@ -31,12 +32,8 @@ root = h.url_for( '/' ) ${ ie.default_javascript_variables() } var notebook_access_url = '${ notebook_access_url }'; - ${ ie.plugin_require_config() } - requirejs(['galaxy.interactive_environments', 'plugin/bam_iobio'], function(IES){ - window.IES = IES; - IES.display_spinner(); - }); + IES.display_spinner(); toastr.info( "BAM io.bio is starting up!", @@ -46,11 +43,8 @@ root = h.url_for( '/' ) var startup = function(){ // Load notebook - requirejs(['galaxy.interactive_environments', 'plugin/bam_iobio'], function(IES){ - window.IES = IES; - IES.load_when_ready(ie_readiness_url, function(){ - load_notebook(notebook_access_url); - }); + IES.load_when_ready(ie_readiness_url, function(){ + load_notebook(notebook_access_url); }); }; diff --git a/config/plugins/interactive_environments/cellxgene/templates/cellxgene.mako b/config/plugins/interactive_environments/cellxgene/templates/cellxgene.mako index 3d91ae1c9b5..8651f5b50af 100644 --- a/config/plugins/interactive_environments/cellxgene/templates/cellxgene.mako +++ b/config/plugins/interactive_environments/cellxgene/templates/cellxgene.mako @@ -21,14 +21,11 @@ ${ ie.default_javascript_variables() } var url = '${ url }'; - ${ ie.plugin_require_config() } - requirejs(['galaxy.interactive_environments'], function (IES) { - $( document ).ready(function() { - IES.keepAlive(url); - IES.test_ie_availability(url, function() { - IES.append_notebook(url); - }); + $( document ).ready(function() { + IES.keepAlive(url); + IES.test_ie_availability(url, function() { + IES.append_notebook(url); }); }); diff --git a/config/plugins/interactive_environments/common/templates/ie.mako b/config/plugins/interactive_environments/common/templates/ie.mako index 63209322228..98fe7919c46 100644 --- a/config/plugins/interactive_environments/common/templates/ie.mako +++ b/config/plugins/interactive_environments/common/templates/ie.mako @@ -1,3 +1,10 @@ +<%def name="load_default_js()"> +${h.css( 'base' ) } +${h.js('bundled/libs.chunk', + 'bundled/base.chunk', + 'bundled/generic.bundled')} + + <%def name="default_javascript_variables()"> // Globals @@ -10,28 +17,15 @@ ie_password = '${ ie_request.notebook_pw }'; var galaxy_root = '${ ie_request.attr.root }'; var app_root = '${ ie_request.attr.app_root }'; var ie_readiness_url = '${ h.url_for("/interactive_environments/ready") }'; - - -<%def name="load_default_js()"> -${h.css( 'base' ) } -${h.js( 'libs/jquery/jquery', - 'libs/toastr', - 'libs/require')} - - -<%def name="plugin_require_config()"> -require.config({ - baseUrl: app_root, - paths: { - "plugin" : app_root + "js", - "galaxy.interactive_environments": "${h.url_for('/static/scripts/galaxy.interactive_environments')}", - }, - urlArgs: "v=${app.server_starttime}", -}); +window.IES = bundleEntries.IES; +window.toastr = bundleEntries.Toast; window.onbeforeunload = function() { return 'You are leaving your Interactive Environment.'; }; + +<%def name="load_default_app()"> + diff --git a/config/plugins/interactive_environments/ethercalc/static/js/ethercalc.js b/config/plugins/interactive_environments/ethercalc/static/js/main.js similarity index 60% rename from config/plugins/interactive_environments/ethercalc/static/js/ethercalc.js rename to config/plugins/interactive_environments/ethercalc/static/js/main.js index bcf564666ae..a9727622ad7 100644 --- a/config/plugins/interactive_environments/ethercalc/static/js/ethercalc.js +++ b/config/plugins/interactive_environments/ethercalc/static/js/main.js @@ -2,8 +2,8 @@ var IES = window.IES; var toastr = window.toastr; -function load_notebook(url){ - IES.test_ie_availability(url, function(){ +function load_notebook(url) { + IES.test_ie_availability(url, function() { IES.append_notebook(url); }); } diff --git a/config/plugins/interactive_environments/ethercalc/templates/ethercalc.mako b/config/plugins/interactive_environments/ethercalc/templates/ethercalc.mako index 5f2e83bd63a..a9c6a60b3e5 100644 --- a/config/plugins/interactive_environments/ethercalc/templates/ethercalc.mako +++ b/config/plugins/interactive_environments/ethercalc/templates/ethercalc.mako @@ -18,20 +18,17 @@ url = ie_request.url_template('${PROXY_URL}/ethercalc/') ${ ie.load_default_js() } +${ ie.load_default_app() }
diff --git a/config/plugins/interactive_environments/hicbrowser/static/js/hicbrowser.js b/config/plugins/interactive_environments/hicbrowser/static/js/main.js similarity index 84% rename from config/plugins/interactive_environments/hicbrowser/static/js/hicbrowser.js rename to config/plugins/interactive_environments/hicbrowser/static/js/main.js index a7803b7d16a..f0164119b9a 100644 --- a/config/plugins/interactive_environments/hicbrowser/static/js/hicbrowser.js +++ b/config/plugins/interactive_environments/hicbrowser/static/js/main.js @@ -3,12 +3,12 @@ var IES = window.IES; // Load an interactive environment (IE) from a remote URL // @param {String} hicexplorer_access_url: the URL embeded in the page and loaded -function load_hicexplorer(hicexplorer_access_url){ +function load_hicexplorer(hicexplorer_access_url) { // When the page has completely loaded... - $( document ).ready(function() { + $(document).ready(function() { // Test if we can access the GIE, and if so, execute the function // to load the GIE for the user. - IES.test_ie_availability(hicexplorer_access_url, function(){ + IES.test_ie_availability(hicexplorer_access_url, function() { IES.append_notebook(hicexplorer_access_url); }); }); diff --git a/config/plugins/interactive_environments/hicbrowser/templates/hicbrowser.mako b/config/plugins/interactive_environments/hicbrowser/templates/hicbrowser.mako index cf69cc8f633..b4ad8329dab 100644 --- a/config/plugins/interactive_environments/hicbrowser/templates/hicbrowser.mako +++ b/config/plugins/interactive_environments/hicbrowser/templates/hicbrowser.mako @@ -29,19 +29,14 @@ ${ ie.load_default_js() } + ${ ie.load_default_app() }
diff --git a/config/plugins/interactive_environments/jupyter/static/js/jupyter.js b/config/plugins/interactive_environments/jupyter/static/js/main.js similarity index 60% rename from config/plugins/interactive_environments/jupyter/static/js/jupyter.js rename to config/plugins/interactive_environments/jupyter/static/js/main.js index 3d386889dba..3d0ac5b7118 100644 --- a/config/plugins/interactive_environments/jupyter/static/js/jupyter.js +++ b/config/plugins/interactive_environments/jupyter/static/js/main.js @@ -2,23 +2,25 @@ var IES = window.IES; var toastr = window.toastr; -function message_failed_auth(password){ +function message_failed_auth(password) { toastr.info( - "Automatic authorization failed. You can manually login with:
" + password + "
More details ...", + "Automatic authorization failed. You can manually login with:
" + + password + + "
More details ...", "Please login manually", - {'closeButton': true, 'timeOut': 100000, 'tapToDismiss': false} + { closeButton: true, timeOut: 100000, tapToDismiss: false } ); } -function message_failed_connection(){ +function message_failed_connection() { toastr.error( "Could not connect to Jupyter Notebook. Please contact your administrator. More details ...", - "Security warning", - {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': true} + "Security warning", + { closeButton: true, timeOut: 20000, tapToDismiss: true } ); } -function message_no_auth(){ +function message_no_auth() { // No longer a security issue, proxy validates Galaxy session token. /* toastr.warning( @@ -29,7 +31,6 @@ function message_no_auth(){ */ } - /** * Load an interactive environment (IE) from a remote URL * @param {String} password: password used to authenticate to the remote resource @@ -37,68 +38,82 @@ function message_no_auth(){ * @param {String} notebook_access_url: the URL embeded in the page and loaded * */ -function load_notebook(password, notebook_login_url, notebook_access_url){ +function load_notebook(password, notebook_login_url, notebook_access_url) { // Test notebook_login_url for accessibility, executing the login+load function whenever // we've successfully connected to the IE. - IES.test_ie_availability(notebook_login_url, function(){ + IES.test_ie_availability(notebook_login_url, function() { _handle_notebook_loading(password, notebook_login_url, notebook_access_url); keep_alive(); }); } - -function keep_alive(){ +function keep_alive() { /** - * This is needed to keep the container alive. If the user leaves this site - * this function is not constantly pinging the container, the container will - * terminate itself. - */ + * This is needed to keep the container alive. If the user leaves this site + * this function is not constantly pinging the container, the container will + * terminate itself. + */ var warn_at = 4; var count_max = 60; // we sleep 15 seconds between requests and the default timeout for the Jupyter container is 120 seconds, so start // with a pretty high ajax timeout. sleep starts low because we want to get the warning up pretty quickly var spin_state = IES.make_spin_state("IE keepalive", 8000, 16000, 2000, 5000, 15000, 5000, false); - var success = function(){ + var success = function() { console.log("IE keepalive request succeeded"); toastr.clear(); - if(spin_state.count >= warn_at){ + if (spin_state.count >= warn_at) { toastr.clear(); - toastr.success( - "Interactive environment connection restored", - {'closeButton': true, 'timeOut': 5000, 'extendedTimeOut': 2000, 'tapToDismiss': true} - ); + toastr.success("Interactive environment connection restored", { + closeButton: true, + timeOut: 5000, + extendedTimeOut: 2000, + tapToDismiss: true + }); } spin_state.count = 0; spin_state.timeout_count = 0; spin_state.error_count = 0; - return false; // keep spinning + return false; // keep spinning }; - var timeout_error = function(jqxhr, status, error){ - console.log("IE keepalive request failed " + spin_state.count + " time(s) of " + count_max + " max: " + status + ": " + error); - if(spin_state.count == warn_at){ + var timeout_error = function(jqxhr, status, error) { + console.log( + "IE keepalive request failed " + + spin_state.count + + " time(s) of " + + count_max + + " max: " + + status + + ": " + + error + ); + if (spin_state.count == warn_at) { toastr.warning( - "Your browser has been unable to contact the interactive environment for " - + spin_state.count + " consecutive attempts, if you do not reestablish " - + "a connection, your IE container may be terminated.", + "Your browser has been unable to contact the interactive environment for " + + spin_state.count + + " consecutive attempts, if you do not reestablish " + + "a connection, your IE container may be terminated.", "Warning", - {'closeButton': true, 'timeOut': 0, 'extendedTimeOut': 0, 'tapToDismiss': false} + { closeButton: true, timeOut: 0, extendedTimeOut: 0, tapToDismiss: false } ); - return false; // keep spinning - }else if(spin_state.count >= count_max){ - IES.spin_error("IE keepalive failure limit reached", "Lost connection to interactive environment, contact your administrator", false); - return true; // stop spinning + return false; // keep spinning + } else if (spin_state.count >= count_max) { + IES.spin_error( + "IE keepalive failure limit reached", + "Lost connection to interactive environment, contact your administrator", + false + ); + return true; // stop spinning } }; console.log("IE keepalive worker starting"); IES.spin(notebook_keepalive_url, false, success, timeout_error, timeout_error, spin_state); } - /** * Must be implemented by IEs */ -function _handle_notebook_loading(password, notebook_login_url, notebook_access_url){ - if ( ie_password_auth ) { +function _handle_notebook_loading(password, notebook_login_url, notebook_access_url) { + if (ie_password_auth) { // Make an AJAX POST $.ajax({ type: "POST", @@ -106,29 +121,28 @@ function _handle_notebook_loading(password, notebook_login_url, notebook_access_ url: notebook_login_url, // With our password data: { - 'password': password + password: password }, xhrFields: { withCredentials: true }, // If that is successful, load the notebook - success: function(){ + success: function() { IES.append_notebook(notebook_access_url); }, - error: function(jqxhr, status, error){ - if(ie_password_auth){ + error: function(jqxhr, status, error) { + if (ie_password_auth) { // Failure happens due to CORS message_failed_auth(password); IES.append_notebook(notebook_access_url); - }else{ + } else { message_failed_connection(); // Do we want to try and load the notebook anyway? Just in case? IES.append_notebook(notebook_access_url); } } }); - } - else { + } else { // Not using password auth, just embed it to avoid content-origin issues. message_no_auth(); IES.append_notebook(notebook_access_url); diff --git a/config/plugins/interactive_environments/jupyter/templates/jupyter.mako b/config/plugins/interactive_environments/jupyter/templates/jupyter.mako index fc8db1f3e5d..eb26eb34fc7 100644 --- a/config/plugins/interactive_environments/jupyter/templates/jupyter.mako +++ b/config/plugins/interactive_environments/jupyter/templates/jupyter.mako @@ -50,6 +50,7 @@ notebook_keepalive_url = ie_request.url_template('${PROXY_URL}/ipython/tree') ${ ie.load_default_js() } +${ ie.load_default_app() } @@ -58,16 +59,10 @@ ${ ie.default_javascript_variables() } var notebook_login_url = '${ notebook_login_url }'; var notebook_access_url = '${ notebook_access_url }'; var notebook_keepalive_url = '${ notebook_keepalive_url }'; -${ ie.plugin_require_config() } // Load notebook - -requirejs(['galaxy.interactive_environments', 'plugin/jupyter'], function(IES){ - // This global is not awesome, get rid of it when possible (when IES are a part of the build process) - window.IES = IES; - IES.load_when_ready(ie_readiness_url, function(){ - load_notebook(ie_password, notebook_login_url, notebook_access_url); - }); +IES.load_when_ready(ie_readiness_url, function(){ + load_notebook(ie_password, notebook_login_url, notebook_access_url); }); diff --git a/config/plugins/interactive_environments/neo/static/js/neo.js b/config/plugins/interactive_environments/neo/static/js/main.js similarity index 76% rename from config/plugins/interactive_environments/neo/static/js/neo.js rename to config/plugins/interactive_environments/neo/static/js/main.js index 37244a7dd6e..06571d8328a 100644 --- a/config/plugins/interactive_environments/neo/static/js/neo.js +++ b/config/plugins/interactive_environments/neo/static/js/main.js @@ -3,10 +3,10 @@ var IES = window.IES; // Load an interactive environment (IE) from a remote URL // @param {String} notebook_access_url: the URL embeded in the page and loaded -function load_notebook(notebook_access_url){ +function load_notebook(notebook_access_url) { // Test if we can access the GIE, and if so, execute the function // to load the GIE for the user. - IES.test_ie_availability(notebook_access_url, function(){ + IES.test_ie_availability(notebook_access_url, function() { IES.append_notebook(notebook_access_url); }); } diff --git a/config/plugins/interactive_environments/neo/templates/neo.mako b/config/plugins/interactive_environments/neo/templates/neo.mako index c1df7807375..24f3e968cd8 100644 --- a/config/plugins/interactive_environments/neo/templates/neo.mako +++ b/config/plugins/interactive_environments/neo/templates/neo.mako @@ -23,20 +23,14 @@ ${ ie.load_default_js() } + ${ ie.load_default_app() } diff --git a/config/plugins/interactive_environments/phinch/static/js/main.js b/config/plugins/interactive_environments/phinch/static/js/main.js new file mode 100644 index 00000000000..be12aeecca2 --- /dev/null +++ b/config/plugins/interactive_environments/phinch/static/js/main.js @@ -0,0 +1,54 @@ +// Globals to be rid of +var IES = window.IES; +var toastr = window.toastr; + +function load_notebook(url) { + IES.test_ie_availability(url, function() { + append_notebook(url); + }); +} + +function append_notebook(url) { + IES.clear_main_area(); + $("#main").append( + '' + ); +} + +function keep_alive(notebook_access_url) { + /** + * This is needed to keep the container alive. If the user leaves this site + * this function is not constantly pinging the container, the container will + * terminate itself. + */ + + var request_count = 0; + var interval = window.setInterval(function() { + $.ajax({ + url: notebook_access_url, + xhrFields: { + withCredentials: true + }, + type: "GET", + timeout: 500, + success: function() { + console.log("Connected to IE, returning"); + }, + error: function(jqxhr, status, error) { + request_count++; + console.log("Request " + request_count); + if (request_count > 30) { + window.clearInterval(interval); + IES.clear_main_area(); + toastr.error("Could not connect to IE, contact your administrator", "Error", { + closeButton: true, + timeOut: 20000, + tapToDismiss: false + }); + } + } + }); + }, 10000); +} diff --git a/config/plugins/interactive_environments/phinch/static/js/phinch.js b/config/plugins/interactive_environments/phinch/static/js/phinch.js deleted file mode 100644 index 1fea1fc08fc..00000000000 --- a/config/plugins/interactive_environments/phinch/static/js/phinch.js +++ /dev/null @@ -1,54 +0,0 @@ -// Globals to be rid of -var IES = window.IES; -var toastr = window.toastr; - -function load_notebook(url){ - IES.test_ie_availability(url, function(){ - append_notebook(url); - }); -} - -function append_notebook(url){ - IES.clear_main_area(); - $('#main').append( - '' - ); -} - - -function keep_alive(notebook_access_url){ - /** - * This is needed to keep the container alive. If the user leaves this site - * this function is not constantly pinging the container, the container will - * terminate itself. - */ - - var request_count = 0; - var interval = window.setInterval(function(){ - $.ajax({ - url: notebook_access_url, - xhrFields: { - withCredentials: true - }, - type: "GET", - timeout: 500, - success: function(){ - console.log("Connected to IE, returning"); - }, - error: function(jqxhr, status, error){ - request_count++; - console.log("Request " + request_count); - if(request_count > 30){ - window.clearInterval(interval); - IES.clear_main_area(); - toastr.error( - "Could not connect to IE, contact your administrator", - "Error", - {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': false} - ); - } - } - }); - }, 10000); -} - diff --git a/config/plugins/interactive_environments/phinch/templates/phinch.mako b/config/plugins/interactive_environments/phinch/templates/phinch.mako index a98e1309cb3..fc84a905ae9 100644 --- a/config/plugins/interactive_environments/phinch/templates/phinch.mako +++ b/config/plugins/interactive_environments/phinch/templates/phinch.mako @@ -21,21 +21,18 @@ url = ie_request.url_template('${PROXY_URL}/phinch/') %> -${ ie.load_default_js() } + ${ ie.load_default_js() } + ${ ie.load_default_app() } diff --git a/config/plugins/interactive_environments/rstudio/static/js/main.js b/config/plugins/interactive_environments/rstudio/static/js/main.js new file mode 100755 index 00000000000..bf4bcac3dfc --- /dev/null +++ b/config/plugins/interactive_environments/rstudio/static/js/main.js @@ -0,0 +1,24 @@ +// Assumed globals we need to get rid of +var IES = window.IES; +var toastr = window.toastr; + +function message_failed_connection() { + toastr.error("Could not connect to RStudio. Please contact your administrator.", "Security warning", { + closeButton: true, + timeOut: 20000, + tapToDismiss: true + }); +} + +/** + * Load an interactive environment (IE) from a remote URL + * @param {String} notebook_access_url: the URL embeded in the page and loaded + * + */ +function load_notebook(notebook_access_url) { + // Test notebook_login_url for accessibility, executing the login+load function whenever + // we've successfully connected to the IE. + IES.test_ie_availability(notebook_access_url, function() { + IES.append_notebook(notebook_access_url); + }); +} diff --git a/config/plugins/interactive_environments/rstudio/static/js/rstudio.js b/config/plugins/interactive_environments/rstudio/static/js/rstudio.js deleted file mode 100755 index c8be493fd5c..00000000000 --- a/config/plugins/interactive_environments/rstudio/static/js/rstudio.js +++ /dev/null @@ -1,32 +0,0 @@ -// Assumed globals we need to get rid of -var IES = window.IES; -var toastr = window.toastr; - -function message_failed_connection(){ - toastr.error( - "Could not connect to RStudio. Please contact your administrator.", - "Security warning", - {'closeButton': true, 'timeOut': 20000, 'tapToDismiss': true} - ); -} - - -/** - * Load an interactive environment (IE) from a remote URL - * @param {String} notebook_access_url: the URL embeded in the page and loaded - * - */ -function load_notebook(notebook_access_url){ - // Test notebook_login_url for accessibility, executing the login+load function whenever - // we've successfully connected to the IE. - IES.test_ie_availability(notebook_access_url, function(){ - $.ajax({ - type: 'GET', - url: notebook_access_url, - success: function(response_text){ - IES.append_notebook(notebook_access_url); - } - }); - - }); -} diff --git a/config/plugins/interactive_environments/rstudio/templates/rstudio.mako b/config/plugins/interactive_environments/rstudio/templates/rstudio.mako index a9c0bf776db..fd181ac41cc 100755 --- a/config/plugins/interactive_environments/rstudio/templates/rstudio.mako +++ b/config/plugins/interactive_environments/rstudio/templates/rstudio.mako @@ -27,18 +27,15 @@ notebook_access_url = ie_request.url_template('${PROXY_URL}/rstudio/') ${ ie.load_default_js() } +${ ie.load_default_app() }
diff --git a/doc/source/admin/galaxy_options.rst b/doc/source/admin/galaxy_options.rst index 82791c59d71..1347cc1aae5 100644 --- a/doc/source/admin/galaxy_options.rst +++ b/doc/source/admin/galaxy_options.rst @@ -105,7 +105,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Description: - Enable's a per request sql debugging option. If this is set to + Enables a per request sql debugging option. If this is set to true, append ?sql_debug=1 to web request URLs to enable detailed logging on the backend of SQL queries generated during that request. This is useful for debugging slow endpoints during @@ -517,7 +517,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Description: - Container resolvers configuration (beta). Setup a file describing + Container resolvers configuration (beta). Set up a file describing container resolvers to use when discovering containers for Galaxy. If this is set to None, the default containers loaded is determined by enable_beta_mulled_containers. @@ -1175,7 +1175,7 @@ :Description: Galaxy can display data at various external browsers. These options specify which browsers should be available. URLs and - builds available at these browsers are defined in the specifield + builds available at these browsers are defined in the specified files. If use_remote_user = True, display application servers will be denied access to Galaxy and so displaying datasets in these sites will fail. display_servers contains a list of @@ -1301,11 +1301,11 @@ URL (with schema http/https) of the Galaxy instance as accessible within your local network - if specified used as a default by pulsar file staging and Jupyter Docker container for communicating - back with Galaxy via the API. If you are attempting to setup GIEs - on Mac OS X with Docker for Mac - this should likely be the IP - address of your machine on the virtualbox network (vboxnet0) setup - for the Docker host VM. This can found by running ifconfig and - using the IP address of the network vboxnet0. + back with Galaxy via the API. If you are attempting to set up + GIEs on Mac OS X with Docker Desktop for Mac and your Galaxy + instance runs on port 8080 this should be + 'http://host.docker.internal:8080'. For more details see + https://docs.docker.com/docker-for-mac/networking/ :Default: ``http://localhost:8080`` :Type: str @@ -1732,9 +1732,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ :Description: - Set the port and IP for the the dynamic proxy to bind to, this - must match the external configuration if dynamic_proxy_manage is - False. + Set the port and IP for the dynamic proxy to bind to, this must + match the external configuration if dynamic_proxy_manage is False. :Default: ``8800`` :Type: int @@ -1744,9 +1743,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~ :Description: - Set the port and IP for the the dynamic proxy to bind to, this - must match the external configuration if dynamic_proxy_manage is - False. + Set the port and IP for the dynamic proxy to bind to, this must + match the external configuration if dynamic_proxy_manage is False. :Default: ``0.0.0.0`` :Type: str diff --git a/doc/source/admin/special_topics/interactive_environments.rst b/doc/source/admin/special_topics/interactive_environments.rst index f075f041295..f7e7fce324c 100644 --- a/doc/source/admin/special_topics/interactive_environments.rst +++ b/doc/source/admin/special_topics/interactive_environments.rst @@ -36,17 +36,13 @@ and `Ansible Galaxy `__. Setting up the Proxy ^^^^^^^^^^^^^^^^^^^^ -Currently the Galaxy proxy is a NodeJS+Sqlite3 proxy. +The Galaxy IE Proxy is a NodeJS+Sqlite3 application. The NodeJS that is +installed by default into the Galaxy Virtualenv is suitable for an execution +environment for the Galaxy IE Proxy. -- Node has recently upgraded, and our proxy is pinned to an old version of - sqlite3. As such you'll currently need to have an older version of Node - available (0.10.X - 0.11.X vintage). -- One can use `NVM `__ to install and manage multiple versions of Node. -- We're working on solutions in this space to provide a better deployment - mechanism here and fewer dependencies. -- Please note that if you have NodeJS installed under Ubuntu, it often - installs to ``/usr/bin/nodejs``, whereas ``npm`` expects it to be - ``/usr/bin/node``. You will need to create that symlink yourself. +- Note that if you have NodeJS installed under Ubuntu, it often installs to + ``/usr/bin/nodejs``, whereas ``npm`` expects it to be ``/usr/bin/node``. You + may need to create that symlink yourself. Once Node and npm are ready to go, you'll need to install the dependencies diff --git a/doc/source/dev/interactive_environments.rst b/doc/source/dev/interactive_environments.rst index a9372fdc228..7f457228c7e 100644 --- a/doc/source/dev/interactive_environments.rst +++ b/doc/source/dev/interactive_environments.rst @@ -205,9 +205,10 @@ We'll continue appending to our ``helloworld.mako`` the HTML code that's actuall - + ${ ie.load_default_js() } + + ${ ie.load_default_app() } @@ -217,18 +218,11 @@ We'll continue appending to our ``helloworld.mako`` the HTML code that's actuall var notebook_login_url = 'unused'; var notebook_access_url = '${ notebook_access_url }'; - // Load code with require.js - ${ ie.plugin_require_config() } // Load notebook - // This will load code from static/helloworld.js, often used to handle - // things like Login. The load_notebook function will eventually append - // an IFrame to the
below. - requirejs(['galaxy.interactive_environments', 'plugin/helloworld'], function(IES){ - window.IES = IES - IES.load_when_ready(ie_readiness_url, function(){ - load_notebook(notebook_access_url); - }); + // The load_notebook function will eventually append an IFrame to the
below. + IES.load_when_ready(ie_readiness_url, function(){ + load_notebook(notebook_access_url); });
@@ -262,7 +256,7 @@ authentication of users, so you don't have to worry about it, and can just assume that only the correct user will have access to a given notebook. In the ``static/`` directory, we generally create a ``js/`` directory below that, -and create a ``{gie}.js`` (so, ``static/js/helloworld.js``) file in there. +and create a ``main.js`` file in there. That file will have a function, ``load_notebook`` which will check if the GIE is available, and when it is, display it to the user. diff --git a/lib/galaxy/visualization/plugins/interactive_environments.py b/lib/galaxy/visualization/plugins/interactive_environments.py index b7c1016f41c..180345c7c1b 100644 --- a/lib/galaxy/visualization/plugins/interactive_environments.py +++ b/lib/galaxy/visualization/plugins/interactive_environments.py @@ -19,7 +19,10 @@ from galaxy import model, web from galaxy.containers import ContainerPort from galaxy.containers.docker_model import DockerVolume from galaxy.managers import api_keys -from galaxy.util import string_as_bool_or_none +from galaxy.util import ( + string_as_bool_or_none, + unicodify +) from galaxy.util.bunch import Bunch @@ -432,6 +435,8 @@ class InteractiveEnvironmentRequest(object): )) p = Popen(raw_cmd, stdout=PIPE, stderr=PIPE, close_fds=True) stdout, stderr = p.communicate() + stdout = unicodify(stdout) + stderr = unicodify(stderr) if p.returncode != 0: log.error("Container Launch error\n\n%s\n%s" % (stdout, stderr)) return None diff --git a/lib/galaxy/webapps/galaxy/config_schema.yml b/lib/galaxy/webapps/galaxy/config_schema.yml index 7447f18be59..70630a407aa 100644 --- a/lib/galaxy/webapps/galaxy/config_schema.yml +++ b/lib/galaxy/webapps/galaxy/config_schema.yml @@ -102,10 +102,10 @@ mapping: default: false required: false desc: | - Enable's a per request sql debugging option. If this is set to true, append - ?sql_debug=1 to web request URLs to enable detailed logging on the backend of SQL - queries generated during that request. This is useful for debugging slow endpoints - during development. + Enables a per request sql debugging option. If this is set to true, + append ?sql_debug=1 to web request URLs to enable detailed logging on + the backend of SQL queries generated during that request. This is + useful for debugging slow endpoints during development. install_database_connection: type: str @@ -397,9 +397,9 @@ mapping: default: '' required: false desc: | - Container resolvers configuration (beta). Setup a file describing container - resolvers to use when discovering containers for Galaxy. If this is set to - None, the default containers loaded is determined by + Container resolvers configuration (beta). Set up a file describing + container resolvers to use when discovering containers for Galaxy. If + this is set to None, the default containers loaded is determined by enable_beta_mulled_containers. involucro_path: @@ -874,7 +874,7 @@ mapping: desc: | Galaxy can display data at various external browsers. These options specify which browsers should be available. URLs and builds available at these - browsers are defined in the specifield files. + browsers are defined in the specified files. If use_remote_user = True, display application servers will be denied access to Galaxy and so displaying datasets in these sites will fail. @@ -970,14 +970,15 @@ mapping: default: http://localhost:8080 required: false desc: | - URL (with schema http/https) of the Galaxy instance as accessible within your - local network - if specified used as a default by pulsar file staging and - Jupyter Docker container for communicating back with Galaxy via the API. + URL (with schema http/https) of the Galaxy instance as accessible + within your local network - if specified used as a default by pulsar + file staging and Jupyter Docker container for communicating back with + Galaxy via the API. - If you are attempting to setup GIEs on Mac OS X with Docker for Mac - this - should likely be the IP address of your machine on the virtualbox network (vboxnet0) - setup for the Docker host VM. This can found by running ifconfig and using the - IP address of the network vboxnet0. + If you are attempting to set up GIEs on Mac OS X with Docker Desktop + for Mac and your Galaxy instance runs on port 8080 this should be + 'http://host.docker.internal:8080'. For more details see + https://docs.docker.com/docker-for-mac/networking/ galaxy_infrastructure_web_port: type: int @@ -1292,7 +1293,7 @@ mapping: default: 8800 required: false desc: | - Set the port and IP for the the dynamic proxy to bind to, this must match + Set the port and IP for the dynamic proxy to bind to, this must match the external configuration if dynamic_proxy_manage is False. dynamic_proxy_bind_ip: @@ -1300,7 +1301,7 @@ mapping: default: 0.0.0.0 required: false desc: | - Set the port and IP for the the dynamic proxy to bind to, this must match + Set the port and IP for the dynamic proxy to bind to, this must match the external configuration if dynamic_proxy_manage is False. dynamic_proxy_debug: