14287: Merge branch 'master' into 14287-federated-list
authorTom Clegg <tclegg@veritasgenetics.com>
Thu, 11 Jul 2019 15:13:12 +0000 (11:13 -0400)
committerTom Clegg <tclegg@veritasgenetics.com>
Thu, 11 Jul 2019 15:13:12 +0000 (11:13 -0400)
Arvados-DCO-1.1-Signed-off-by: Tom Clegg <tclegg@veritasgenetics.com>

129 files changed:
apps/workbench/app/controllers/actions_controller.rb
apps/workbench/app/controllers/application_controller.rb
apps/workbench/app/controllers/collections_controller.rb
apps/workbench/app/controllers/container_requests_controller.rb
apps/workbench/app/controllers/containers_controller.rb
apps/workbench/app/controllers/healthcheck_controller.rb
apps/workbench/app/controllers/jobs_controller.rb
apps/workbench/app/controllers/pipeline_instances_controller.rb
apps/workbench/app/controllers/pipeline_templates_controller.rb
apps/workbench/app/controllers/projects_controller.rb
apps/workbench/app/controllers/users_controller.rb
apps/workbench/app/controllers/virtual_machines_controller.rb
apps/workbench/app/controllers/work_units_controller.rb
apps/workbench/app/controllers/workflows_controller.rb
apps/workbench/app/helpers/application_helper.rb
apps/workbench/app/helpers/collections_helper.rb
apps/workbench/app/mailers/issue_reporter.rb
apps/workbench/app/mailers/request_shell_access_reporter.rb
apps/workbench/app/models/arvados_api_client.rb
apps/workbench/app/models/repository.rb
apps/workbench/app/views/api_client_authorizations/_show_help.html.erb
apps/workbench/app/views/application/_breadcrumbs.html.erb
apps/workbench/app/views/application/_report_error.html.erb
apps/workbench/app/views/application/_report_issue_popup.html.erb
apps/workbench/app/views/application/_show_sharing.html.erb
apps/workbench/app/views/collections/show_file_links.html.erb
apps/workbench/app/views/getting_started/_getting_started_popup.html.erb
apps/workbench/app/views/jobs/_show_log.html.erb
apps/workbench/app/views/layouts/application.html.erb
apps/workbench/app/views/layouts/body.html.erb
apps/workbench/app/views/notifications/_collections_notification.html.erb
apps/workbench/app/views/notifications/_jobs_notification.html.erb
apps/workbench/app/views/notifications/_pipelines_notification.html.erb
apps/workbench/app/views/projects/_show_dashboard.html.erb
apps/workbench/app/views/repositories/_show_help.html.erb
apps/workbench/app/views/user_agreements/index.html.erb
apps/workbench/app/views/users/_add_ssh_key_popup.html.erb
apps/workbench/app/views/users/_current_token.html.erb
apps/workbench/app/views/users/_setup_popup.html.erb
apps/workbench/app/views/users/_ssh_keys.html.erb
apps/workbench/app/views/users/_tables.html.erb
apps/workbench/app/views/users/_virtual_machines.html.erb
apps/workbench/app/views/users/profile.html.erb
apps/workbench/app/views/users/welcome.html.erb
apps/workbench/app/views/virtual_machines/_show_help.html.erb
apps/workbench/app/views/virtual_machines/webshell.html.erb
apps/workbench/app/views/work_units/_show_log.html.erb
apps/workbench/config/application.default.yml
apps/workbench/config/application.rb
apps/workbench/config/arvados_config.rb [new file with mode: 0644]
apps/workbench/config/load_config.rb [deleted file]
apps/workbench/fpm-info.sh
apps/workbench/lib/config_loader.rb [new file with mode: 0644]
apps/workbench/lib/config_validators.rb
apps/workbench/lib/tasks/config.rake [new file with mode: 0644]
apps/workbench/lib/tasks/config_check.rake [deleted file]
apps/workbench/lib/tasks/config_dump.rake [deleted file]
apps/workbench/test/controllers/actions_controller_test.rb
apps/workbench/test/controllers/application_controller_test.rb
apps/workbench/test/controllers/collections_controller_test.rb
apps/workbench/test/controllers/disabled_api_test.rb
apps/workbench/test/controllers/projects_controller_test.rb
apps/workbench/test/controllers/users_controller_test.rb
apps/workbench/test/integration/anonymous_access_test.rb
apps/workbench/test/integration/application_layout_test.rb
apps/workbench/test/integration/download_test.rb
apps/workbench/test/integration/errors_test.rb
apps/workbench/test/integration/jobs_test.rb
apps/workbench/test/integration/link_account_test.rb
apps/workbench/test/integration/projects_test.rb
apps/workbench/test/integration/report_issue_test.rb
apps/workbench/test/integration/user_profile_test.rb
apps/workbench/test/integration/user_settings_menu_test.rb
apps/workbench/test/integration/websockets_test.rb
apps/workbench/test/integration/work_units_test.rb
apps/workbench/test/integration_helper.rb
apps/workbench/test/integration_performance/collection_unit_test.rb
apps/workbench/test/test_helper.rb
apps/workbench/test/unit/user_test.rb
apps/workbench/test/unit/work_unit_test.rb
build/package-build-dockerfiles/Makefile
build/package-build-dockerfiles/centos7/Dockerfile
build/package-build-dockerfiles/debian8/Dockerfile
build/package-build-dockerfiles/debian9/Dockerfile
build/package-build-dockerfiles/ubuntu1404/Dockerfile
build/package-build-dockerfiles/ubuntu1604/Dockerfile
build/package-build-dockerfiles/ubuntu1804/Dockerfile
build/rails-package-scripts/postinst.sh
build/run-build-packages.sh
build/run-library.sh
build/run-tests.sh
cmd/arvados-server/cmd.go
doc/_includes/_admin_list_collections_without_property_py.liquid
doc/_includes/_admin_set_property_to_collections_under_project_py.liquid
doc/_includes/_admin_update_collection_property_py.liquid
doc/admin/config-migration.html.textile.liquid
doc/admin/upgrading.html.textile.liquid
doc/api/methods.html.textile.liquid
doc/install/index.html.textile.liquid
doc/install/install-api-server.html.textile.liquid
doc/install/install-dispatch-cloud.html.textile.liquid
doc/install/install-workbench-app.html.textile.liquid
doc/sdk/cli/reference.html.textile.liquid
lib/cloud/cloudtest/cmd.go
lib/cloud/cloudtest/tester.go
lib/config/cmd.go
lib/config/config.default.yml
lib/config/export.go
lib/config/generated_config.go
sdk/cwl/arvados_cwl/fsaccess.py
sdk/go/arvados/config.go
services/api/config/arvados_config.rb
services/api/config/config.default.yml [deleted symlink]
services/api/fpm-info.sh
services/login-sync/Gemfile.lock
tools/arvbox/bin/arvbox
tools/arvbox/lib/arvbox/docker/api-setup.sh
tools/arvbox/lib/arvbox/docker/service/controller/run
tools/arvbox/lib/arvbox/docker/service/workbench/run-service
tools/crunchstat-summary/crunchstat_summary/dygraphs.py
tools/crunchstat-summary/crunchstat_summary/summarizer.py
tools/crunchstat-summary/crunchstat_summary/webchart.py
tools/crunchstat-summary/tests/container_9tee4-dz642-lymtndkpy39eibk-arv-mount.txt.gz.report
tools/crunchstat-summary/tests/container_9tee4-dz642-lymtndkpy39eibk-crunchstat.txt.gz.report
tools/crunchstat-summary/tests/container_9tee4-dz642-lymtndkpy39eibk.txt.gz.report
tools/crunchstat-summary/tests/logfile_20151204190335.txt.gz.report
tools/crunchstat-summary/tests/logfile_20151210063411.txt.gz.report
tools/crunchstat-summary/tests/logfile_20151210063439.txt.gz.report
tools/crunchstat-summary/tests/test_examples.py

index b1bbb122670dcb6b11aac21d915f26174851aed9..e6f20be37064ea7f396206ca0b7d68ae3482ef09 100644 (file)
@@ -10,7 +10,7 @@ class ActionsController < ApplicationController
   # Skip require_thread_api_token if this is a show action
   # for an object uuid that supports anonymous access.
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name and
     params['uuid'] and
     model_class.in?([Collection, Group, Job, PipelineInstance, PipelineTemplate])
index f913a15ffe23c997c7e5554f9755a470599c2e4c..ccd0abdc33e5245c2c05014e5d7cd176f297961b 100644 (file)
@@ -756,14 +756,14 @@ class ApplicationController < ActionController::Base
   def missing_required_profile?
     missing_required = false
 
-    profile_config = Rails.configuration.user_profile_form_fields
-    if current_user && profile_config
+    profile_config = Rails.configuration.Workbench.UserProfileFormFields
+    if current_user && !profile_config.empty?
       current_user_profile = current_user.prefs[:profile]
-      profile_config.kind_of?(Array) && profile_config.andand.each do |entry|
-        if entry['required']
+      profile_config.each do |k, entry|
+        if entry['Required']
           if !current_user_profile ||
-             !current_user_profile[entry['key'].to_sym] ||
-             current_user_profile[entry['key'].to_sym].empty?
+             !current_user_profile[k] ||
+             current_user_profile[k].empty?
             missing_required = true
             break
           end
@@ -775,13 +775,13 @@ class ApplicationController < ActionController::Base
   end
 
   def select_theme
-    return Rails.configuration.arvados_theme
+    return Rails.configuration.Workbench.Theme
   end
 
   @@notification_tests = []
 
   @@notification_tests.push lambda { |controller, current_user|
-    return nil if Rails.configuration.shell_in_a_box_url
+    return nil if Rails.configuration.Services.WebShell.ExternalURL != URI("")
     AuthorizedKey.limit(1).where(authorized_user_uuid: current_user.uuid).each do
       return nil
     end
@@ -815,7 +815,7 @@ class ApplicationController < ActionController::Base
   helper_method :user_notifications
   def user_notifications
     @errors = nil if !defined?(@errors)
-    return [] if @errors or not current_user.andand.is_active or not Rails.configuration.show_user_notifications
+    return [] if @errors or not current_user.andand.is_active or not Rails.configuration.Workbench.ShowUserNotifications
     @notifications ||= @@notification_tests.map do |t|
       t.call(self, current_user)
     end.compact
index 8d7e6ee332af5e3cf53dac674e6185626f43d413..5141012443c33f9dc98492cf41535219d0f6a2a4 100644 (file)
@@ -10,7 +10,7 @@ class CollectionsController < ApplicationController
   include ActionController::Live
 
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
   skip_around_action(:require_thread_api_token,
@@ -124,7 +124,8 @@ class CollectionsController < ApplicationController
     # Otherwise, it's impossible to know whether any other request succeeded
     # because of the reader token.
     coll = nil
-    tokens = [(Rails.configuration.anonymous_user_token || nil),
+    tokens = [(if !Rails.configuration.Users.AnonymousUserToken.empty? then
+                Rails.configuration.Users.AnonymousUserToken else nil end),
               params[:reader_token],
               Thread.current[:arvados_api_token]].compact
     usable_token = find_usable_token(tokens) do
@@ -138,7 +139,7 @@ class CollectionsController < ApplicationController
     opts = {}
     if usable_token == params[:reader_token]
       opts[:path_token] = usable_token
-    elsif usable_token == Rails.configuration.anonymous_user_token
+    elsif usable_token == Rails.configuration.Users.AnonymousUserToken
       # Don't pass a token at all
     else
       # We pass the current user's real token only if it's necessary
@@ -334,24 +335,25 @@ class CollectionsController < ApplicationController
 
   def keep_web_url(uuid_or_pdh, file, opts)
     munged_id = uuid_or_pdh.sub('+', '-')
-    fmt = {uuid_or_pdh: munged_id}
 
-    tmpl = Rails.configuration.keep_web_url
-    if Rails.configuration.keep_web_download_url and
-        (!tmpl or opts[:disposition] == 'attachment')
+    tmpl = Rails.configuration.Services.WebDAV.ExternalURL.to_s
+
+    if Rails.configuration.Services.WebDAVDownload.ExternalURL != URI("") and
+        (tmpl.empty? or opts[:disposition] == 'attachment')
       # Prefer the attachment-only-host when we want an attachment
       # (and when there is no preview link configured)
-      tmpl = Rails.configuration.keep_web_download_url
-    elsif not Rails.configuration.trust_all_content
-      check_uri = URI.parse(tmpl % fmt)
+      tmpl = Rails.configuration.Services.WebDAVDownload.ExternalURL.to_s
+    elsif not Rails.configuration.Workbench.TrustAllContent
+      check_uri = URI.parse(tmpl.sub("*", munged_id))
       if opts[:query_token] and
+        (check_uri.host.nil? or (
           not check_uri.host.start_with?(munged_id + "--") and
-          not check_uri.host.start_with?(munged_id + ".")
+          not check_uri.host.start_with?(munged_id + ".")))
         # We're about to pass a token in the query string, but
         # keep-web can't accept that safely at a single-origin URL
         # template (unless it's -attachment-only-host).
-        tmpl = Rails.configuration.keep_web_download_url
-        if not tmpl
+        tmpl = Rails.configuration.Services.WebDAVDownload.ExternalURL.to_s
+        if tmpl.empty?
           raise ArgumentError, "Download precluded by site configuration"
         end
         logger.warn("Using download link, even though inline content " \
@@ -359,13 +361,16 @@ class CollectionsController < ApplicationController
       end
     end
 
-    if tmpl == Rails.configuration.keep_web_download_url
+    if tmpl == Rails.configuration.Services.WebDAVDownload.ExternalURL.to_s
       # This takes us to keep-web's -attachment-only-host so there is
       # no need to add ?disposition=attachment.
       opts.delete :disposition
     end
 
-    uri = URI.parse(tmpl % fmt)
+    uri = URI.parse(tmpl.sub("*", munged_id))
+    if tmpl.index("*").nil?
+      uri.path = "/c=#{munged_id}"
+    end
     uri.path += '/' unless uri.path.end_with? '/'
     if opts[:path_token]
       uri.path += 't=' + opts[:path_token] + '/'
index d5627076f5e1d0b0dee23531fbe884dacb16aa64..385d9dc6d7292c8cc5d47cf18b94ecf5189b8354 100644 (file)
@@ -4,7 +4,7 @@
 
 class ContainerRequestsController < ApplicationController
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
 
index a8549cd5b82e8b9e82420d7f7478b2c3a9660247..4b5606778f409f072fd44e4449200eb73ed788d0 100644 (file)
@@ -4,7 +4,7 @@
 
 class ContainersController < ApplicationController
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
 
index 7afe4032a2c19f726465e8aae7b1f6cdf55dafc0..691bef8ee578bbd3beeb616906ac44a4df253631 100644 (file)
@@ -19,7 +19,7 @@ class HealthcheckController < ApplicationController
     mgmt_token = Rails.configuration.ManagementToken
     auth_header = request.headers['Authorization']
 
-    if !mgmt_token
+    if mgmt_token.empty?
       render :json => {:errors => "disabled"}, :status => 404
     elsif !auth_header
       render :json => {:errors => "authorization required"}, :status => 401
index e38d3ba87b3e40e6df08e4d6150a2a3c392220a7..4f7bfcee53e5f11acceefc5c2a0d1707287143c1 100644 (file)
@@ -4,7 +4,7 @@
 
 class JobsController < ApplicationController
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
 
@@ -67,7 +67,7 @@ class JobsController < ApplicationController
 
   def logs
     @logs = @object.
-      stderr_log_query(Rails.configuration.running_job_log_records_to_fetch).
+      stderr_log_query(Rails.configuration.Workbench.RunningJobLogRecordsToFetch).
       map { |e| e.serializable_hash.merge({ 'prepend' => true }) }
     respond_to do |format|
       format.json { render json: @logs }
index 26a9f85d4e4e890b85ab722151737afe12d2dd12..c8863653a1b8f30433ce77d2570bd831cc7cfbd7 100644 (file)
@@ -6,7 +6,7 @@ class PipelineInstancesController < ApplicationController
   skip_before_action :find_object_by_uuid, only: :compare
   before_action :find_objects_by_uuid, only: :compare
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
 
index c497c70d434c4b67edb1dab42c2558bdd8242b16..aa444c153b6163d3a65d43bbeb790d2c06688844 100644 (file)
@@ -4,7 +4,7 @@
 
 class PipelineTemplatesController < ApplicationController
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
 
index 8237dc7152c9e72dddf2ace2515bf8b80f0b1294..b649b710b01598d73c3c53f19a54df2152dd75aa 100644 (file)
@@ -5,7 +5,7 @@
 class ProjectsController < ApplicationController
   before_action :set_share_links, if: -> { defined? @object and @object}
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     %w(show tab_counts public).include? ctrl.action_name
   }
 
@@ -315,8 +315,8 @@ class ProjectsController < ApplicationController
   end
 
   def public  # Yes 'public' is the name of the action for public projects
-    return render_not_found if not Rails.configuration.anonymous_user_token or not Rails.configuration.enable_public_projects_page
-    @objects = using_specific_api_token Rails.configuration.anonymous_user_token do
+    return render_not_found if Rails.configuration.Users.AnonymousUserToken.empty? or not Rails.configuration.Workbench.EnablePublicProjectsPage
+    @objects = using_specific_api_token Rails.configuration.Users.AnonymousUserToken do
       Group.where(group_class: 'project').order("modified_at DESC")
     end
   end
index d934af796509e2c172dcda8d2941daf889acd716..b27482c4cc47351bd474244205c8f60ea634f8ea 100644 (file)
@@ -202,7 +202,7 @@ class UsersController < ApplicationController
     respond_to do |format|
       if current_user.andand.is_admin
         setup_params = {}
-        setup_params[:send_notification_email] = "#{Rails.configuration.send_user_setup_notification_email}"
+        setup_params[:send_notification_email] = "#{Rails.configuration.Mail.SendUserSetupNotificationEmail}"
         if params['user_uuid'] && params['user_uuid'].size>0
           setup_params[:uuid] = params['user_uuid']
         end
index 19763b926c78077b97de261d49714d37c0c6b7bb..764571c4c5b635352439fa7d0e09f2d2431e39e9 100644 (file)
@@ -25,11 +25,14 @@ class VirtualMachinesController < ApplicationController
   end
 
   def webshell
-    return render_not_found if not Rails.configuration.shell_in_a_box_url
-    @webshell_url = Rails.configuration.shell_in_a_box_url % {
-      uuid: @object.uuid,
-      hostname: @object.hostname,
-    }
+    return render_not_found if Rails.configuration.Workbench.ShellInABoxURL == URI("")
+    webshell_url = URI(Rails.configuration.Workbench.ShellInABoxURL)
+    if webshell_url.host.index("*") != nil
+      webshell_url.host = webshell_url.host.sub("*", @object.hostname)
+    else
+      webshell_url.path = "/#{@object.hostname}"
+    end
+    @webshell_url = webshell_url.to_s
     render layout: false
   end
 
index 0f0033ce4965663ef76a7f2e479d8e38d7642dfb..1ecea99babce40e6755839889d0f6dad6ef26b18 100644 (file)
@@ -4,7 +4,7 @@
 
 class WorkUnitsController < ApplicationController
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show_child_component' == ctrl.action_name
   }
 
index b7f99e855e69dab591e633d9a07a54baa6f03282..4d78ca7ed92f834086b91c6f83a04d31ea2e94b1 100644 (file)
@@ -4,7 +4,7 @@
 
 class WorkflowsController < ApplicationController
   skip_around_action :require_thread_api_token, if: proc { |ctrl|
-    Rails.configuration.anonymous_user_token and
+    !Rails.configuration.Users.AnonymousUserToken.empty? and
     'show' == ctrl.action_name
   }
 
index 6352916b00b14560af0683aa9594b6daf7ce20ca..0a872446d594d42f8485316663b437cbfab0c3c8 100644 (file)
@@ -12,11 +12,11 @@ module ApplicationHelper
   end
 
   def current_api_host
-    Rails.configuration.arvados_v1_base.gsub(/https?:\/\/|\/arvados\/v1/, '')
+    "#{Rails.configuration.Services.Controller.ExternalURL.hostname}:#{Rails.configuration.Services.Controller.ExternalURL.port}"
   end
 
   def current_uuid_prefix
-    current_api_host[0..4]
+    Rails.configuration.ClusterID
   end
 
   def render_markup(markup)
index 5eb1e8c768d927dfdc14e814143d2a945ed0c011..0c89ca8783c0c45b523a33c4c8fd495ce17f0c58 100644 (file)
@@ -72,7 +72,7 @@ module CollectionsHelper
     elsif (file_type.raw_media_type == "text") || (file_type.raw_media_type == "image")
       true
     elsif (file_type.raw_media_type == "application") &&
-          (Rails.configuration.application_mimetypes_with_view_icon.include? (file_type.sub_type))
+          Rails.configuration.Workbench.ApplicationMimetypesWithViewIcon[file_type.sub_type]
       true
     else
       false
index de07122c2fba3a86a169ad32c6a9ed62dc5e81e5..8066b0b5bb83112c4309e0958eae97a8899e5e92 100644 (file)
@@ -3,8 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0
 
 class IssueReporter < ActionMailer::Base
-  default from: Rails.configuration.issue_reporter_email_from
-  default to: Rails.configuration.issue_reporter_email_to
+  default from: Rails.configuration.Mail.IssueReporterEmailFrom
+  default to: Rails.configuration.Mail.IssueReporterEmailTo
 
   def send_report(user, params)
     @user = user
index 8615cea3a86648ec88a28d0421c039852f470ff6..32de8d7821e2a9ce4430cb1abb475aedff7b76fb 100644 (file)
@@ -3,8 +3,8 @@
 # SPDX-License-Identifier: AGPL-3.0
 
 class RequestShellAccessReporter < ActionMailer::Base
-  default from: Rails.configuration.email_from
-  default to: Rails.configuration.support_email_address
+  default from: Rails.configuration.Mail.EmailFrom
+  default to: Rails.configuration.Mail.SupportEmailAddress
 
   def send_request(user, params)
     @user = user
index ce91cd3057bf4915d8e673af9c93e9ec6fbea75d..3c9bfa793daa5a8ba143cbbf8fc40122654b6fff 100644 (file)
@@ -61,7 +61,7 @@ class ArvadosApiClient
     404 => NotFoundException,
   }
 
-  @@profiling_enabled = Rails.configuration.profiling_enabled
+  @@profiling_enabled = Rails.configuration.Workbench.ProfilingEnabled
   @@discovery = nil
 
   # An API client object suitable for handling API requests on behalf
@@ -89,10 +89,10 @@ class ArvadosApiClient
     if not @api_client
       @client_mtx.synchronize do
         @api_client = HTTPClient.new
-        @api_client.ssl_config.timeout = Rails.configuration.api_client_connect_timeout
-        @api_client.connect_timeout = Rails.configuration.api_client_connect_timeout
-        @api_client.receive_timeout = Rails.configuration.api_client_receive_timeout
-        if Rails.configuration.arvados_insecure_https
+        @api_client.ssl_config.timeout = Rails.configuration.Workbench.APIClientConnectTimeout
+        @api_client.connect_timeout = Rails.configuration.Workbench.APIClientConnectTimeout
+        @api_client.receive_timeout = Rails.configuration.Workbench.APIClientReceiveTimeout
+        if Rails.configuration.TLS.Insecure
           @api_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
         else
           # Use system CA certificates
@@ -101,7 +101,7 @@ class ArvadosApiClient
             .select { |ca_path| File.readable?(ca_path) }
             .each { |ca_path| @api_client.ssl_config.add_trust_ca(ca_path) }
         end
-        if Rails.configuration.api_response_compression
+        if Rails.configuration.Workbench.APIResponseCompression
           @api_client.transparent_gzip_decompression = true
         end
       end
@@ -113,7 +113,7 @@ class ArvadosApiClient
     # Clean up /arvados/v1/../../discovery/v1 to /discovery/v1
     url.sub! '/arvados/v1/../../', '/'
 
-    anon_tokens = [Rails.configuration.anonymous_user_token].select { |x| x && include_anon_token }
+    anon_tokens = [Rails.configuration.Users.AnonymousUserToken].select { |x| !x.empty? && include_anon_token }
 
     query = {
       'reader_tokens' => ((tokens[:reader_tokens] ||
@@ -235,17 +235,13 @@ class ArvadosApiClient
   end
 
   def arvados_login_url(params={})
-    if Rails.configuration.respond_to? :arvados_login_base
-      uri = Rails.configuration.arvados_login_base
-    else
-      uri = self.arvados_v1_base.sub(%r{/arvados/v\d+.*}, '/login')
-    end
-    if params.size > 0
-      uri += '?' << params.collect { |k,v|
-        CGI.escape(k.to_s) + '=' + CGI.escape(v.to_s)
-      }.join('&')
+    uri = URI.parse(Rails.configuration.Services.Controller.ExternalURL.to_s)
+    if Rails.configuration.testing_override_login_url
+      uri = URI(Rails.configuration.testing_override_login_url)
     end
-    uri
+    uri.path = "/login"
+    uri.query = URI.encode_www_form(params)
+    uri.to_s
   end
 
   def arvados_logout_url(params={})
@@ -253,7 +249,11 @@ class ArvadosApiClient
   end
 
   def arvados_v1_base
-    Rails.configuration.arvados_v1_base
+    # workaround Ruby 2.3 bug, can't duplicate URI objects
+    # https://github.com/httprb/http/issues/388
+    u = URI.parse(Rails.configuration.Services.Controller.ExternalURL.to_s)
+    u.path = "/arvados/v1"
+    u.to_s
   end
 
   def discovery
index 6e8b68bd6e0bac1eb06a8501e3520b68bc6817ba..8b89d57ee904d92bc481d8b2b54dedf6c2cdb140 100644 (file)
@@ -76,9 +76,9 @@ class Repository < ArvadosBase
   # non-zero.
   def run_git *gitcmd
     if not @workdir
-      workdir = File.expand_path uuid+'.git', Rails.configuration.repository_cache
+      workdir = File.expand_path uuid+'.git', Rails.configuration.Workbench.RepositoryCache
       if not File.exists? workdir
-        FileUtils.mkdir_p Rails.configuration.repository_cache
+        FileUtils.mkdir_p Rails.configuration.Workbench.RepositoryCache
         [['git', 'init', '--bare', workdir],
         ].each do |cmd|
           system *cmd
@@ -94,7 +94,7 @@ class Repository < ArvadosBase
       '!cred(){ cat >/dev/null; if [ "$1" = get ]; then echo password=$ARVADOS_API_TOKEN; fi; };cred'],
      ['git', '--git-dir', @workdir, 'config', '--local',
            'http.sslVerify',
-           Rails.configuration.arvados_insecure_https ? 'false' : 'true'],
+           Rails.configuration.TLS.Insecure ? 'false' : 'true'],
      ].each do |cmd|
       system *cmd
       raise GitCommandError.new($?.to_s) unless $?.exitstatus == 0
index 0118390e5b6ad923727bdafef31728e3955766fa..18907ed71b6fe433dc06eb35b8f68a2799866891 100644 (file)
@@ -10,7 +10,7 @@ read ARVADOS_API_TOKEN &lt;&lt;EOF
 <%= Thread.current[:arvados_api_token] %>
 EOF
 export ARVADOS_API_TOKEN ARVADOS_API_HOST=<%= current_api_host %>
-<% if Rails.configuration.arvados_insecure_https %>
+<% if Rails.configuration.TLS.Insecure %>
 export ARVADOS_API_HOST_INSECURE=true
 <% else %>
 unset ARVADOS_API_HOST_INSECURE
index 7a2d08e54a1afa4faacb3041f0268eaec47f0094..c3c2e07da7ddb776c2a489918b19540bebc9b036 100644 (file)
@@ -31,7 +31,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                     <i class="glyphicon fa-fw glyphicon-search"></i> Search all projects ...
                   <% end %>
                </li>
-              <% if Rails.configuration.anonymous_user_token and Rails.configuration.enable_public_projects_page %>
+              <% if !Rails.configuration.Users.AnonymousUserToken.empty? and Rails.configuration.Workbench.EnablePublicProjectsPage %>
                 <li role="menuitem"><a href="/projects/public" role="menuitem"><i class="fa fa-fw fa-list"></i> Browse public projects </a>
                 </li>
               <% end %>
index ab0fd67d3a11cada3052dba88e29414229da6799..6027208b28272f2d01fc3936258e3088d1fd4a4a 100644 (file)
@@ -27,7 +27,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 
 or
 
-<%= mail_to(Rails.configuration.support_email_address, "email us",
+<%= mail_to(Rails.configuration.Mail.SupportEmailAddress, "email us",
             subject: "Workbench problem report",
             body: "Problem while viewing page #{request.url}") %>
 
index 8823fdd5f78f8ebfe7c4a336c3a144bc479de26f..3dc332651fd40aaa17c2104833e0257bdb02f13d 100644 (file)
@@ -4,8 +4,8 @@ SPDX-License-Identifier: AGPL-3.0 %>
 
 <%
   generated_at = arvados_api_client.discovery[:generatedAt]
-  arvados_base = Rails.configuration.arvados_v1_base
-  support_email = Rails.configuration.support_email_address
+  arvados_base = Rails.configuration.Services.Controller.ExternalURL.to_s + "/arvados/v1"
+  support_email = Rails.configuration.Mail.SupportEmailAddress
 
   additional_info = {}
   additional_info['Current location'] = params[:current_location]
index 8403ee0b4fe20345d92cbf2e30fe843150b6d635..7877e60d3018096bdc3ad6b9ef4c4bd892631925 100644 (file)
@@ -26,7 +26,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
    choose_filters = {
      "groups" => [["group_class", "=", "role"]],
    }
-   if not Rails.configuration.anonymous_user_token
+   if Rails.configuration.Users.AnonymousUserToken.empty?
      # It would be ideal to filter out the anonymous group by UUID,
      # but that's not readily doable.  Workbench can't generate the
      # UUID for a != filter, because it can't introspect the API
index 8a2ce6b8268195605ba370153c1292be0a2a0c03..a82d2556e7c94a2be04d376447016635ff92e5f7 100644 (file)
@@ -10,7 +10,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 <head>
   <meta charset="utf-8">
   <title>
-    <%= coll_name %> / <%= Rails.configuration.site_name %>
+    <%= coll_name %> / <%= Rails.configuration.Workbench.SiteName %>
   </title>
   <meta name="description" content="">
   <meta name="author" content="">
index fa75ec26e27cad11f8d896efe8867e63977e041d..99880f2416e4a8a88371e2c06c76cf904b38900f 100644 (file)
@@ -98,7 +98,7 @@ div.figure p {
                 <li>
                   Also known as a “workflow” in other systems
                 </li><li>
-                  A list of well-documented public pipelines can be found in the upper right corner by clicking the <span class="fa fa-lg fa-question-circle"></span> &gt; <a href="<%= Rails.configuration.arvados_public_data_doc_url %>">Public Pipelines and Datasets</a>
+                  A list of well-documented public pipelines can be found in the upper right corner by clicking the <span class="fa fa-lg fa-question-circle"></span> &gt; <a href="<%= Rails.configuration.Workbench.ArvadosPublicDataDocURL %>">Public Pipelines and Datasets</a>
                 </li><li>
                   Pro-tip: A Pipeline contains Jobs which contain Tasks
                 </li><li>
index e84641d431205cdf816822836071183a61009822..10b7fa1c4eec3090c47a7ce60bacaf87b22ec8b8 100644 (file)
@@ -12,7 +12,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 <pre id="event_log_div"
      class="arv-log-event-listener arv-log-event-handler-append-logs arv-job-log-window"
      data-object-uuid="<%= @object.uuid %>"
-  ><%= @object.stderr_log_lines(Rails.configuration.running_job_log_records_to_fetch).join("\n") %>
+  ><%= @object.stderr_log_lines(Rails.configuration.Workbench.RunningJobLogRecordsToFetch).join("\n") %>
 </pre>
 
 <%# Applying a long throttle suppresses the auto-refresh of this
@@ -68,7 +68,7 @@ var makeFilter = function() {
   <% logcollection = Collection.find @object.log %>
   <% if logcollection %>
     var log_size = <%= logcollection.files[0][2] %>
-    var log_maxbytes = <%= Rails.configuration.log_viewer_max_bytes %>;
+    var log_maxbytes = <%= Rails.configuration.Workbench.LogViewerMaxBytes %>;
     var logcollection_url = '<%=j url_for logcollection %>/<%=j logcollection.files[0][1] %>';
     $("#log-viewer-download-url").attr('href', logcollection_url);
     $("#log-viewer-download-pane").show();
index 638ee8970c35a5b5af83528d7b3e650e0e487cc3..bd3afbb681f098a1f3fe726e7d9bc49f671240ac 100644 (file)
@@ -8,9 +8,9 @@ SPDX-License-Identifier: AGPL-3.0 %>
   <meta charset="utf-8">
   <title>
     <% if content_for? :page_title %>
-    <%= yield :page_title %> / <%= Rails.configuration.site_name %>
+    <%= yield :page_title %> / <%= Rails.configuration.Workbench.SiteName %>
     <% else %>
-    <%= Rails.configuration.site_name %>
+    <%= Rails.configuration.Workbench.SiteName %>
     <% end %>
   </title>
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -20,7 +20,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
   <meta name="author" content="">
   <% if current_user %>
     <% content_for :js do %>
-      window.defaultSession = <%=raw({baseURL: Rails.configuration.arvados_v1_base.sub(/\/arvados\/v1$/, '/'), token: Thread.current[:arvados_api_token], user: current_user}.to_json)%>
+      window.defaultSession = <%=raw({baseURL: Rails.configuration.Services.Controller.ExternalURL.to_s, token: Thread.current[:arvados_api_token], user: current_user}.to_json)%>
     <% end %>
   <% end %>
   <% if current_user and $arvados_api_client.discovery[:websocketUrl] %>
@@ -32,7 +32,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
       social graph that search engines can use. http://ogp.me/ %>
   <meta property="og:type" content="article" />
   <meta property="og:url" content="<%= request.url %>" />
-  <meta property="og:site_name" content="<%= Rails.configuration.site_name %>" />
+  <meta property="og:site_name" content="<%= Rails.configuration.Workbench.SiteName %>" />
   <% if defined?(@object) && @object %>
     <% if @object.respond_to?(:name) and @object.name.present? %>
       <meta property="og:title" content="<%= @object.name%>" />
@@ -49,7 +49,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
   <%= yield :head %>
   <%= javascript_tag do %>
     angular.module('Arvados').value('arvadosApiToken', '<%=Thread.current[:arvados_api_token]%>');
-    angular.module('Arvados').value('arvadosDiscoveryUri', '<%= Rails.configuration.arvados_v1_base.sub '/arvados/v1', '/discovery/v1/apis/arvados/v1/rest' %>');
+    angular.module('Arvados').value('arvadosDiscoveryUri', '<%= Rails.configuration.Services.Controller.ExternalURL.to_s + '/discovery/v1/apis/arvados/v1/rest' %>');
   <%= yield :js %>
   <% end %>
   <style>
index b2cd097f3174c03fa49c7d1f280d7c809ecf280c..9da55cbeb3fedd36a3add088ab8a9d0e29607ed1 100644 (file)
@@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
         </button>
-        <% site_name = Rails.configuration.site_name.downcase rescue Rails.application.class.parent_name %>
+        <% site_name = Rails.configuration.Workbench.SiteName.downcase rescue Rails.application.class.parent_name %>
         <% if current_user %>
           <a class="navbar-brand" href="/" data-push=true><%= site_name %></a>
         <% else %>
@@ -28,12 +28,12 @@ SPDX-License-Identifier: AGPL-3.0 %>
 
           <% if current_user %>
             <% if current_user.is_active %>
-              <% if Rails.configuration.multi_site_search %>
+              <% if !Rails.configuration.Workbench.MultiSiteSearch.empty? %>
                 <li>
                   <form class="navbar-form">
                     <%=
-                       target = Rails.configuration.multi_site_search
-                       if target == true
+                       target = Rails.configuration.Workbench.MultiSiteSearch
+                       if target == "true"
                          target = {controller: 'search', action: 'index'}
                        end
                        link_to("Multi-site search", target, {class: 'btn btn-default'}) %>
@@ -72,9 +72,9 @@ SPDX-License-Identifier: AGPL-3.0 %>
                 </li>
                 <% if current_user.is_active %>
                 <li role="menuitem"><a href="/projects/<%=current_user.uuid%>" role="menuitem"><i class="fa fa-lg fa-home fa-fw"></i> Home project </a></li>
-                  <% if Rails.configuration.composer_url %>
+                  <% if Rails.configuration.Services.Composer.ExternalURL != URI("") %>
                     <li role="menuitem">
-                     <form action="<%= Rails.configuration.composer_url %>" method="GET">
+                     <form action="<%= Rails.configuration.Services.Composer.ExternalURL.to_s %>" method="GET">
                        <input type="hidden" name="api_token" value="<%= Thread.current[:arvados_api_token] %>" />
                        <button role="menuitem" type="submit">
                          <i class="fa fa-lg fa-share-alt fa-fw"></i> Workflow Composer
@@ -82,10 +82,10 @@ SPDX-License-Identifier: AGPL-3.0 %>
                      </form>
                     </li>
                   <% end %>
-                <% if Rails.configuration.workbench2_url %>
+                <% if Rails.configuration.Services.Workbench2.ExternalURL != URI("") %>
                 <li role="menuitem">
                   <%
-                    wb2_url = Rails.configuration.workbench2_url
+                    wb2_url = Rails.configuration.Services.Workbench2.ExternalURL.to_s
                     wb2_url += '/' if wb2_url[-1] != '/'
                     wb2_url += 'token'
                   %>
@@ -102,7 +102,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                     <i class="fa fa-lg fa-terminal fa-fw"></i> Virtual machines
                   <% end %>
                 </li>
-                <% if Rails.configuration.repositories %>
+                <% if Rails.configuration.Workbench.Repositories %>
                 <li role="menuitem"><a href="/repositories" role="menuitem"><i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories </a></li>
                 <% end -%>
                 <li role="menuitem"><a href="/current_token" role="menuitem"><i class="fa fa-lg fa-ticket fa-fw"></i> Current token</a></li>
@@ -112,7 +112,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                   <% end %>
 </li>
                 <li role="menuitem"><a href="/users/link_account" role="menuitem"><i class="fa fa-lg fa-link fa-fw"></i> Link account </a></li>
-                <% if Rails.configuration.user_profile_form_fields %>
+                <% if !Rails.configuration.Workbench.UserProfileFormFields.empty? %>
                   <li role="menuitem"><a href="/users/<%=current_user.uuid%>/profile" role="menuitem"><i class="fa fa-lg fa-user fa-fw"></i> Manage profile</a></li>
                 <% end %>
                 <% end %>
@@ -138,7 +138,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                   <li role="presentation" class="dropdown-header">
                     Admin Settings
                   </li>
-                  <% if Rails.configuration.repositories %>
+                  <% if Rails.configuration.Workbench.Repositories %>
                   <li role="menuitem"><a href="/repositories">
                       <i class="fa fa-lg fa-code-fork fa-fw"></i> Repositories
                   </a></li>
@@ -174,7 +174,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
               </li>
             <% end %>
           <% else %>
-            <% if Rails.configuration.anonymous_user_token and Rails.configuration.enable_public_projects_page %>
+            <% if !Rails.configuration.Users.AnonymousUserToken.empty? and Rails.configuration.Workbench.EnablePublicProjectsPage %>
               <li><%= link_to 'Browse public projects', "/projects/public" %></li>
             <% end %>
             <li class="dropdown hover-dropdown login-menu">
@@ -199,18 +199,18 @@ SPDX-License-Identifier: AGPL-3.0 %>
               <li role="presentation" class="dropdown-header">
                 Help
               </li>
-              <% if Rails.configuration.enable_getting_started_popup %>
+              <% if Rails.configuration.Workbench.EnableGettingStartedPopup %>
                 <li>
                 <%= link_to raw('<i class="fa fa-fw fa-info"></i> Getting Started ...'), "#",
                      {'data-toggle' => "modal", 'data-target' => '#getting-started-modal-window'}  %>
                 </li>
               <% end %>
-              <% if Rails.configuration.arvados_public_data_doc_url %>
-                <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> Public Pipelines and Data sets'), "#{Rails.configuration.arvados_public_data_doc_url}", target: "_blank" %></li>
+              <% if !Rails.configuration.Workbench.ArvadosPublicDataDocURL.empty? %>
+                <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> Public Pipelines and Data sets'), "#{Rails.configuration.Workbench.ArvadosPublicDataDocURL}", target: "_blank" %></li>
               <% end %>
-              <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> Tutorials and User guide'), "#{Rails.configuration.arvados_docsite}/user", target: "_blank" %></li>
-              <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> API Reference'), "#{Rails.configuration.arvados_docsite}/api", target: "_blank" %></li>
-              <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> SDK Reference'), "#{Rails.configuration.arvados_docsite}/sdk", target: "_blank" %></li>
+              <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> Tutorials and User guide'), "#{Rails.configuration.Workbench.ArvadosDocsite}/user", target: "_blank" %></li>
+              <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> API Reference'), "#{Rails.configuration.Workbench.ArvadosDocsite}/api", target: "_blank" %></li>
+              <li><%= link_to raw('<i class="fa fa-book fa-fw"></i> SDK Reference'), "#{Rails.configuration.Workbench.ArvadosDocsite}/sdk", target: "_blank" %></li>
               <li role="presentation" class="divider"></li>
               <li> <%= link_to report_issue_popup_path(popup_type: 'version', current_location: request.url, current_path: request.fullpath, action_method: 'post'),
                       {class: 'report-issue-modal-window', remote: true, return_to: request.url} do %>
@@ -264,7 +264,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 <div id="report-issue-modal-window"></div>
 <script src="/browser_unsupported.js"></script>
 
-<%  if Rails.configuration.enable_getting_started_popup and current_user and !current_user.prefs[:getting_started_shown] and
+<%  if Rails.configuration.Workbench.EnableGettingStartedPopup and current_user and !current_user.prefs[:getting_started_shown] and
        !request.url.include?("/profile") and
        !request.url.include?("/user_agreements") and
        !request.url.include?("/inactive")%>
index 22643bf5a10dfe03bdc36db7724d733d5ac1944f..7769046cf950b7564fd6889a6209462a05080577 100644 (file)
@@ -4,8 +4,8 @@ SPDX-License-Identifier: AGPL-3.0 %>
 
   <%= image_tag "dax.png", class: "dax" %>
   <p>
-    Hi, I noticed you haven't uploaded a new collection yet. 
-    <%= link_to "Click here to learn how to upload data to Arvados Keep.", 
-       "#{Rails.configuration.arvados_docsite}/user/tutorials/tutorial-keep.html", 
+    Hi, I noticed you haven't uploaded a new collection yet.
+    <%= link_to "Click here to learn how to upload data to Arvados Keep.",
+       "#{Rails.configuration.Workbench.ArvadosDocsite}/user/tutorials/tutorial-keep.html",
        style: "font-weight: bold", target: "_blank" %>
   </p>
index d9cc7a667e3b9b260dbc3977dbd44feb767b9558..d793ea0b2b56ce005b211647b2b7d803975d841c 100644 (file)
@@ -3,10 +3,9 @@
 SPDX-License-Identifier: AGPL-3.0 %>
 
   <p><%= image_tag "dax.png", class: "dax" %>
-    Hi, I noticed you haven't run a job yet. 
-    <%= link_to "Click here to learn how to run an Arvados Crunch job.", 
-       "#{Rails.configuration.arvados_docsite}/user/tutorials/tutorial-job1.html", 
+    Hi, I noticed you haven't run a job yet.
+    <%= link_to "Click here to learn how to run an Arvados Crunch job.",
+       "#{Rails.configuration.Workbench.ArvadosDocsite}/user/tutorials/tutorial-job1.html",
        style: "font-weight: bold",
        target: "_blank" %>
   </p>
-
index e70fc59d40bf2402a48e56d823ceb6298e8c008b..b275ed8eaa217cad8925d59f193ef6a08d5b1c79 100644 (file)
@@ -3,9 +3,9 @@
 SPDX-License-Identifier: AGPL-3.0 %>
 
   <p><%= image_tag "dax.png", class: "dax" %>
-    Hi, I noticed you haven't run a pipeline yet.  
-    <%= link_to "Click here to learn how to run an Arvados Crunch pipeline.", 
-       "#{Rails.configuration.arvados_docsite}/user/tutorials/tutorial-pipeline-workbench.html",
+    Hi, I noticed you haven't run a pipeline yet.
+    <%= link_to "Click here to learn how to run an Arvados Crunch pipeline.",
+       "#{Rails.configuration.Workbench.ArvadosDocsite}/user/tutorials/tutorial-pipeline-workbench.html",
        style: "font-weight: bold",
        target: "_blank" %>
   </p>
index 22d89fff6d8e9133b310f9a6efcc2a4d22040c69..71ef2454190d7625cae12cf77d44f05a1ad7ed27 100644 (file)
@@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
   collection_pdhs = outputs.select {|x| !(m = CollectionsHelper.match(x)).nil?}.uniq.compact
   collection_uuids = outputs - collection_pdhs
 
-  if Rails.configuration.show_recent_collections_on_dashboard
+  if Rails.configuration.Workbench.ShowRecentCollectionsOnDashboard
     recent_cs = recent_collections(8)
     collection_uuids = collection_uuids + recent_cs[:collections].collect {|c| c.uuid}
     collection_uuids.flatten.uniq
@@ -42,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
     show_node_status = false
     # Recent processes panel should take the entire width when is the only one
     # being rendered.
-    if !Rails.configuration.show_recent_collections_on_dashboard
+    if !Rails.configuration.Workbench.ShowRecentCollectionsOnDashboard
       recent_procs_panel_width = 12
     end
   else
@@ -197,7 +197,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
        </div>
       </div>
       <% end %>
-      <% if Rails.configuration.show_recent_collections_on_dashboard %>
+      <% if Rails.configuration.Workbench.ShowRecentCollectionsOnDashboard %>
       <div class="panel panel-default">
         <div class="panel-heading"><span class="panel-title">Recent collections</span>
           <span class="pull-right">
index 5904fb29db8a513d05f0d9532cf666b650c1bb49..4a7b45491183a9bec056ded0f3220594f63b5df4 100644 (file)
@@ -28,10 +28,10 @@ git push
 <p>
   See also:
   <%= link_to raw('Arvados Docs &rarr; User Guide &rarr; SSH access'),
-  "#{Rails.configuration.arvados_docsite}/user/getting_started/ssh-access-unix.html",
-      target: "_blank"%> and 
+  "#{Rails.configuration.Workbench.ArvadosDocsite}/user/getting_started/ssh-access-unix.html",
+      target: "_blank"%> and
   <%= link_to raw('Arvados Docs &rarr; User Guide &rarr; Writing a Crunch
   Script'),
-  "#{Rails.configuration.arvados_docsite}/user/tutorials/tutorial-firstscript.html",
+  "#{Rails.configuration.Workbench.ArvadosDocsite}/user/tutorials/tutorial-firstscript.html",
   target: "_blank"%>.
 </p>
index 5f70c4735b69c4ffd3fdf28c2e048ef1c45e9869..d52ad649c94853865aea6d606d66fbc8e3131d6b 100644 (file)
@@ -19,7 +19,7 @@ User agreements
   <div class="alert alert-info">
     <strong>Please check <%= n_files > 1 ? 'each' : 'the' %> box below</strong> to indicate that you have read and accepted the user agreement<%= 's' if n_files > 1 %>.
   </div>
-  <% if n_files == 1 and (Rails.configuration.show_user_agreement_inline rescue false) %>
+  <% if n_files == 1 and (Rails.configuration.Workbench.ShowUserAgreementInline rescue false) %>
   <% ua = unsigned_user_agreements.first; file = ua.files.first %>
   <object data="<%= url_for(controller: 'collections', action: 'show_file', uuid: ua.uuid, file: "#{file[0]}/#{file[1]}") %>" type="<%= Rack::Mime::MIME_TYPES[file[1].match(/\.\w+$/)[0]] rescue '' %>" width="100%" height="400px">
   </object>
index 5abaf155df6a0f90be733ad8c5599352fe450342..1d0814c2a01549f0e2fc840a45c990d36d0de0f3 100644 (file)
@@ -18,7 +18,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 
       <div class="modal-body">
         <div> <%= link_to "Click here to learn about SSH keys in Arvados.",
-                  "#{Rails.configuration.arvados_docsite}/user/getting_started/ssh-access-unix.html",
+                  "#{Rails.configuration.Workbench.ArvadosDocsite}/user/getting_started/ssh-access-unix.html",
                   style: "font-weight: bold",
                   target: "_blank" %>
         </div>
index deab2d722448b2000776cf335609b4932e1e5882..6b1ec33a2666545e7b2b71a6e012788a6caee995 100644 (file)
@@ -12,14 +12,14 @@ SPDX-License-Identifier: AGPL-3.0 %>
   </div>
 
 <div id="#manage_current_token" class="panel-body">
-<p>The Arvados API token is a secret key that enables the Arvados SDKs to access Arvados with the proper permissions. For more information see <%= link_to raw('Getting an API token'), "#{Rails.configuration.arvados_docsite}/user/reference/api-tokens.html", target: "_blank"%>.</p>
+<p>The Arvados API token is a secret key that enables the Arvados SDKs to access Arvados with the proper permissions. For more information see <%= link_to raw('Getting an API token'), "#{Rails.configuration.Workbench.ArvadosDocsite}/user/reference/api-tokens.html", target: "_blank"%>.</p>
 <p>Paste the following lines at a shell prompt to set up the necessary environment for Arvados SDKs to authenticate to your <b><%= current_user.username %></b> account.</p>
 
 <pre>
 HISTIGNORE=$HISTIGNORE:'export ARVADOS_API_TOKEN=*'
 export ARVADOS_API_TOKEN=<%= Thread.current[:arvados_api_token] %>
 export ARVADOS_API_HOST=<%= current_api_host %>
-<% if Rails.configuration.arvados_insecure_https %>
+<% if Rails.configuration.TLS.Insecure %>
 export ARVADOS_API_HOST_INSECURE=true
 <% else %>
 unset ARVADOS_API_HOST_INSECURE
index 3b3794bf50a8b791e23ef006d623c5ff121ca66a..d6f25136c438a39c6eb9659c198effec62afbd69 100644 (file)
@@ -44,7 +44,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                value="<%=identity_url_prefix%>" disabled=true>
         <% else %>
         <input class="form-control" id="openid_prefix" maxlength="250" name="openid_prefix" type="text"
-               value="<%= Rails.configuration.default_openid_prefix %>">
+               value="<%= Rails.configuration.Workbench.DefaultOpenIdPrefix %>">
         <% end %>
       </div>
       <div class="form-group">
index 8d2f51364e4d0aab5b80a796aebc0289ce5d1098..fa26bc4aa1af8f379edb8d73c7026475a5d7c149 100644 (file)
@@ -19,7 +19,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 <div id="manage_ssh_keys" class="panel-body">
   <% if !@my_ssh_keys.any? %>
      <p> You have not yet set up an SSH public key for use with Arvados. <%= link_to "Learn more.",
-                  "#{Rails.configuration.arvados_docsite}/user/getting_started/ssh-access-unix.html",
+                  "#{Rails.configuration.Workbench.ArvadosDocsite}/user/getting_started/ssh-access-unix.html",
                   style: "font-weight: bold",
                   target: "_blank" %>
      </p>
index 5667951124378a8a34990138529935627e4b7946..01a77cdd6188fd35ea409e9c8e90c7f5babb29b4 100644 (file)
@@ -251,7 +251,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
           Your account must be activated by an Arvados administrator.  If this
           is your first time accessing Arvados and would like to request
           access, or you believe you are seeing the page in error, please
-          <%= link_to "contact us", Rails.configuration.activation_contact_link %>.
+          <%= link_to "contact us", Rails.configuration.Workbench.ActivationContactLink %>.
           You should receive an email at the address you used to log in when
           your account is activated.  In the mean time, you can
           <%= link_to "learn more about Arvados", "https://arvados.org/projects/arvados/wiki/Introduction_to_Arvados" %>,
@@ -259,7 +259,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
         </p>
         <p style="padding-bottom: 1em">
           <%= link_to raw('Contact us &#x2709;'),
-              Rails.configuration.activation_contact_link, class: "pull-right btn btn-primary" %></p>
+              Rails.configuration.Workbench.ActivationContactLink, class: "pull-right btn btn-primary" %></p>
       </div>
     </div>
   </div>
index c891b0c594af329b9f0a7790217596b11b0109fc..026f016f8cd7186ebcc6eb39e123ae0dcbb5e9dc 100644 (file)
@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
 <div id="manage_virtual_machines" class="panel-body">
   <p>
     For more information see <%= link_to raw('Arvados Docs &rarr; User Guide &rarr; VM access'),
-  "#{Rails.configuration.arvados_docsite}/user/getting_started/vm-login-with-webshell.html",
+  "#{Rails.configuration.Workbench.ArvadosDocsite}/user/getting_started/vm-login-with-webshell.html",
   target: "_blank"%>.
   </p>
 
@@ -68,7 +68,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
           <th> Host name </th>
           <th> Login name </th>
           <th> Command line </th>
-          <% if Rails.configuration.shell_in_a_box_url %>
+          <% if Rails.configuration.Services.WebShell.ExternalURL != URI("") %>
             <th> Web shell <span class="label label-info">beta</span></th>
           <% end %>
         </tr>
@@ -89,7 +89,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
                 <% end %>
               <% end %>
             </td>
-            <% if Rails.configuration.shell_in_a_box_url %>
+            <% if Rails.configuration.Services.WebShell.ExternalURL != URI("") %>
               <td>
                 <% @my_vm_logins[vm[:uuid]].andand.each do |login| %>
                   <%= link_to webshell_virtual_machine_path(vm, login: login), title: "Open a terminal session in your browser", class: 'btn btn-xs btn-default', target: "_blank" do %>
index 26d1f57211b257a524461dd70f049a3e2afd9bf6..6692196dabf717e40defd77e9c6c0c2538d3c393 100644 (file)
@@ -3,11 +3,18 @@
 SPDX-License-Identifier: AGPL-3.0 %>
 
 <%
-    profile_config = Rails.configuration.user_profile_form_fields
+    profile_config = []
+    Rails.configuration.Workbench.UserProfileFormFields.each do |k, v|
+      r = v.dup
+      r["Key"] = k
+      profile_config << r
+    end
+    profile_config.sort_by! { |v| v["Position"] }
+
     current_user_profile = current_user.prefs[:profile]
     show_save_button = false
 
-    profile_message = Rails.configuration.user_profile_form_message
+    profile_message = Rails.configuration.Workbench.UserProfileFormMessage
 %>
 
 <div>
@@ -61,29 +68,29 @@ SPDX-License-Identifier: AGPL-3.0 %>
               </div>
 
               <% profile_config.kind_of?(Array) && profile_config.andand.each do |entry| %>
-                <% if entry['key'] %>
+                <% if entry['Key'] %>
                   <%
                       show_save_button = true
-                      label = entry['required'] ? '* ' : ''
-                      label += entry['form_field_title']
-                      value = current_user_profile[entry['key'].to_sym] if current_user_profile
+                      label = entry['Required'] ? '* ' : ''
+                      label += entry['FormFieldTitle']
+                      value = current_user_profile[entry['Key'].to_sym] if current_user_profile
                   %>
                   <div class="form-group">
-                    <label for="<%=entry['key']%>"
+                    <label for="<%=entry['Key']%>"
                            class="col-sm-3 control-label"
-                           style=<%="color:red" if entry['required']&&(!value||value.empty?)%>> <%=label%>
+                           style=<%="color:red" if entry['Required']&&(!value||value.empty?)%>> <%=label%>
                     </label>
-                    <% if entry['type'] == 'select' %>
+                    <% if entry['Type'] == 'select' %>
                       <div class="col-sm-8">
-                        <select class="form-control" name="user[prefs][profile][<%=entry['key']%>]">
-                          <% entry['options'].each do |option| %>
+                        <select class="form-control" name="user[prefs][profile][<%=entry['Key']%>]">
+                          <% entry['Options'].each do |option, _| %>
                             <option value="<%=option%>" <%='selected' if option==value%>><%=option%></option>
                           <% end %>
                         </select>
                       </div>
                     <% else %>
                       <div class="col-sm-8">
-                        <input type="text" class="form-control" name="user[prefs][profile][<%=entry['key']%>]" placeholder="<%=entry['form_field_description']%>" value="<%=value%>" ></input>
+                        <input type="text" class="form-control" name="user[prefs][profile][<%=entry['Key']%>]" placeholder="<%=entry['FormFieldDescription']%>" value="<%=value%>" ></input>
                       </div>
                     <% end %>
                   </div>
index b10ca8b15de8f8c6778dad98050bb978d0599de3..479e3e1d89dec50c5d6398ad3e7dc470be211d8c 100644 (file)
@@ -16,17 +16,17 @@ SPDX-License-Identifier: AGPL-3.0 %>
         The "Log in" button below will show you a Google sign-in page.
         After you assure Google that you want to log in here with your
         Google account, you will be redirected back here to
-        <%= Rails.configuration.site_name %>.
+        <%= Rails.configuration.Workbench.SiteName %>.
 
       </p><p>
 
-        If you have never used <%= Rails.configuration.site_name %>
+        If you have never used <%= Rails.configuration.Workbench.SiteName %>
         before, logging in for the first time will automatically
         create a new account.
 
       </p><p>
 
-        <i><%= Rails.configuration.site_name %> uses your name and
+        <i><%= Rails.configuration.Workbench.SiteName %> uses your name and
           email address only for identification, and does not retrieve
           any other personal information from Google.</i>
 
@@ -36,7 +36,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
             now, don't provide 'auth_provider' to get the default one. %>
         <div class="pull-right">
           <%= link_to arvados_api_client.arvados_login_url(return_to: request.url), class: "btn btn-primary" do %>
-          Log in to <%= Rails.configuration.site_name %>
+          Log in to <%= Rails.configuration.Workbench.SiteName %>
           <i class="fa fa-fw fa-arrow-circle-right"></i>
           <% end %>
         </div>
index 13916572cef9d8bd381809e1f8928504a9310995..204e71a9147e6b9e5317e8882192800d6178af44 100644 (file)
@@ -25,6 +25,6 @@ ssh <%= @objects.first.andand.hostname.andand.sub('.'+current_api_host,'') or 'v
 <p>
   See also:
   <%= link_to raw('Arvados Docs &rarr; User Guide &rarr; SSH access'),
-  "#{Rails.configuration.arvados_docsite}/user/getting_started/ssh-access-unix.html",
+  "#{Rails.configuration.Workbench.ArvadosDocsite}/user/getting_started/ssh-access-unix.html",
   target: "_blank"%>.
 </p>
index 202ae70fb0083a8fe722267a063c96efdf0ec5ba..4c63115a1669cb389cf9c97d77fa6fef75a056b3 100644 (file)
@@ -3,7 +3,7 @@
 SPDX-License-Identifier: AGPL-3.0 %>
 
 <html>
-    <title><%= @object.hostname %> / <%= Rails.configuration.site_name %></title>
+    <title><%= @object.hostname %> / <%= Rails.configuration.Workbench.SiteName %></title>
     <link rel="stylesheet" href="<%= asset_path 'webshell/styles.css' %>" type="text/css">
     <style type="text/css">
       body {
index 1f643acdc9ff6a1dc042a3de86f6ab9a78357481..d2c565750c9f76e86b47c390bd63cf3b15df4d79 100644 (file)
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0 %>
   </div>
 <% end %>
 
-<% live_log_lines = wu.live_log_lines(Rails.configuration.running_job_log_records_to_fetch).join("\n") %>
+<% live_log_lines = wu.live_log_lines(Rails.configuration.Workbench.RunningJobLogRecordsToFetch).join("\n") %>
 <% if !render_log or (live_log_lines.size > 0) %>
 <%# Still running, or recently finished and logs are still available from logs table %>
 <%# Show recent logs in terminal window %>
index d38742248b52fac025d72bf95f89c86e91c29380..8d1dff995248d9f98feaea4b77ff5ba723b0a738 100644 (file)
@@ -53,12 +53,6 @@ development:
   action_dispatch.best_standards_support: :builtin
   assets.debug: true
   profiling_enabled: true
-  site_name: Arvados Workbench (dev)
-
-  # API server configuration
-  arvados_login_base: ~
-  arvados_v1_base: ~
-  arvados_insecure_https: ~
 
 production:
   force_ssl: true
@@ -73,18 +67,6 @@ production:
   profiling_enabled: false
   log_level: info
 
-  arvados_insecure_https: false
-
-  data_import_dir: /data/arvados-workbench-upload/data
-  data_export_dir: /data/arvados-workbench-download/data
-
-  # API server configuration
-  arvados_login_base: ~
-  arvados_v1_base: ~
-  arvados_insecure_https: ~
-
-  site_name: Arvados Workbench
-
 test:
   cache_classes: true
   eager_load: false
@@ -130,67 +112,11 @@ test:
         - IT
         - Other
 
+  repository_cache: <%= File.expand_path 'tmp/git', Rails.root %>
+
 common:
   assets.js_compressor: false
   assets.css_compressor: false
-  data_import_dir: /tmp/arvados-workbench-upload
-  data_export_dir: /tmp/arvados-workbench-download
-  arvados_login_base: https://arvados.local/login
-  arvados_v1_base: https://arvados.local/arvados/v1
-  arvados_insecure_https: true
-  activation_contact_link: mailto:info@arvados.org
-  arvados_docsite: http://doc.arvados.org
-  arvados_public_data_doc_url: http://arvados.org/projects/arvados/wiki/Public_Pipelines_and_Datasets
-  arvados_theme: default
-  show_user_agreement_inline: false
-  secret_token: ~
-  secret_key_base: false
-  default_openid_prefix: https://www.google.com/accounts/o8/id
-  send_user_setup_notification_email: true
-
-  # Scratch directory used by the remote repository browsing
-  # feature. If it doesn't exist, it (and any missing parents) will be
-  # created using mkdir_p.
-  repository_cache: <%= File.expand_path 'tmp/git', Rails.root %>
-
-  # Set user_profile_form_fields to enable and configure the user
-  # profile page. Default is set to false. A commented example with
-  # full description is provided below.
-  user_profile_form_fields: false
-
-  # Below is a sample setting of user_profile_form_fields config parameter.
-  # This configuration parameter should be set to either false (to disable) or
-  # to an array as shown below.
-  # Configure the list of input fields to be displayed in the profile page
-  # using the attribute "key" for each of the input fields.
-  # This sample shows configuration with one required and one optional form fields.
-  # For each of these input fields:
-  #   You can specify "type" as "text" or "select".
-  #   List the "options" to be displayed for each of the "select" menu.
-  #   Set "required" as "true" for any of these fields to make them required.
-  # If any of the required fields are missing in the user's profile, the user will be
-  # redirected to the profile page before they can access any Workbench features.
-  #user_profile_form_fields:
-  #  - key: organization
-  #    type: text
-  #    form_field_title: Institution/Company
-  #    form_field_description: Your organization
-  #    required: true
-  #  - key: role
-  #    type: select
-  #    form_field_title: Your role
-  #    form_field_description: Choose the category that best describes your role in your organization.
-  #    options:
-  #      - Bio-informatician
-  #      - Computational biologist
-  #      - Biologist or geneticist
-  #      - Software developer
-  #      - IT
-  #      - Other
-
-  # Use "user_profile_form_message" to configure the message you want to display on
-  # the profile page.
-  user_profile_form_message: Welcome to Arvados. All <span style="color:red">required fields</span> must be completed before you can proceed.
 
   # Override the automatic version string. With the default value of
   # false, the version string is read from git-commit.version in
@@ -203,131 +129,5 @@ common:
   # Rails.root (included in vendor packages).
   package_version: false
 
-  # report notification to and from addresses
-  issue_reporter_email_from: arvados@example.com
-  issue_reporter_email_to: arvados@example.com
-  support_email_address: arvados@example.com
-
-  # generic issue email from
-  email_from: arvados@example.com
-
-  # Mimetypes of applications for which the view icon
-  # would be enabled in a collection's show page.
-  # It is sufficient to list only applications here.
-  # No need to list text and image types.
-  application_mimetypes_with_view_icon: [cwl, fasta, go, javascript, json, pdf, python, x-python, r, rtf, sam, x-sh, vnd.realvnc.bed, xml, xsl]
-
-  # the maximum number of bytes to load in the log viewer
-  log_viewer_max_bytes: 1000000
-
-  # Set anonymous_user_token to enable anonymous user access. You can get
-  # the token by running "bundle exec ./script/get_anonymous_user_token.rb"
-  # in the directory where your API server is running.
-  anonymous_user_token: false
-
-  # when anonymous_user_token is configured, show public projects page
-  enable_public_projects_page: true
-
-  # by default, disable the "Getting Started" popup which is specific to the public beta install
-  enable_getting_started_popup: false
-
-  # Ask Arvados API server to compress its response payloads.
-  api_response_compression: true
-
-  # Timeouts for API requests.
-  api_client_connect_timeout: 120
-  api_client_receive_timeout: 300
-
-  # ShellInABox service endpoint URL for a given VM.  If false, do not
-  # offer web shell logins.
-  #
-  # E.g., using a path-based proxy server to forward connections to shell hosts:
-  # https://webshell.uuid_prefix.arvadosapi.com/%{hostname}
-  #
-  # E.g., using a name-based proxy server to forward connections to shell hosts:
-  # https://%{hostname}.webshell.uuid_prefix.arvadosapi.com/
-  shell_in_a_box_url: false
-
-  # Format of preview links. If false, use keep_web_download_url
-  # instead, and disable inline preview.
-  # If both are false, Workbench won't start, this is a mandatory configuration.
-  #
-  # Examples:
-  # keep_web_url: https://%{uuid_or_pdh}.collections.uuid_prefix.arvadosapi.com
-  # keep_web_url: https://%{uuid_or_pdh}--collections.uuid_prefix.arvadosapi.com
-  #
-  # Example supporting only public data and collection-sharing links
-  # (other data will be handled as downloads via keep_web_download_url):
-  # keep_web_url: https://collections.uuid_prefix.arvadosapi.com/c=%{uuid_or_pdh}
-  keep_web_url: false
-
-  # Format of download links. If false, use keep_web_url with
-  # disposition=attachment query param.
-  #
-  # The host part of the keep_web_download_url value here must match
-  # the -attachment-only-host argument given to keep-web: if
-  # keep_web_download_url is "https://FOO.EXAMPLE/c=..." then keep-web
-  # must run with "-attachment-only-host=FOO.EXAMPLE".
-  #
-  # If keep_web_download_url is false, and keep_web_url uses a
-  # single-origin form, then Workbench will show an error page
-  # when asked to download or preview private data.
-  #
-  # Example:
-  # keep_web_download_url: https://download.uuid_prefix.arvadosapi.com/c=%{uuid_or_pdh}
-  keep_web_download_url: false
-
-  # In "trust all content" mode, Workbench will redirect download
-  # requests to keep-web, even in the cases when keep-web would have
-  # to expose XSS vulnerabilities in order to handle the redirect.
-  #
-  # When enabling this setting, the -trust-all-content flag on the
-  # keep-web server must also be enabled.  For more detail, see
-  # https://godoc.org/github.com/curoverse/arvados/services/keep-web
-  #
-  # This setting has no effect in the recommended configuration, where
-  # the host part of keep_web_url begins with %{uuid_or_pdh}: in this
-  # case XSS protection is provided by browsers' same-origin policy.
-  #
-  # The default setting (false) is appropriate for a multi-user site.
-  trust_all_content: false
-
-  # Maximum number of historic log records of a running job to fetch
-  # and display in the Log tab, while subscribing to web sockets.
-  running_job_log_records_to_fetch: 2000
-
-  # In systems with many shared projects, loading of dashboard and topnav
-  # cab be slow due to collections indexing; use the following parameters
-  # to suppress these properties
-  show_recent_collections_on_dashboard: true
-  show_user_notifications: true
-
-  # Token to be included in all healthcheck requests. Disabled by default.
-  # Workbench expects request header of the format "Authorization: Bearer xxx"
-  ManagementToken: false
-
-  # Enable/disable "multi-site search" in top nav (true/false), or
-  # link it to the multi-site search on a remote Workbench site.
-  #
-  # Example:
-  # multi_site_search: https://workbench.qr1hi.arvadosapi.com/collections/multisite
-  multi_site_search: false
-
-  #
-  # Link to use for Arvados Workflow Composer app, or false if not available.
-  #
-  composer_url: false
-
-  #
-  # Should workbench allow management of local git repositories? Set to false if
-  # the jobs api is disabled and there are no local git repositories.
-  #
-  repositories: true
-
-  #
-  # Add an item to the user menu pointing to workbench2_url, if not false.
-  #
-  # Example:
-  # workbench2_url: https://workbench2.qr1hi.arvadosapi.com
-  #
-  workbench2_url: false
+  # only used by tests
+  testing_override_login_url: false
index 1c7a9d0dac8866511f795e1fea048d7f4989a300..514d57196d3fcc802dbc83a640907bbf166ceb76 100644 (file)
@@ -21,6 +21,9 @@ Bundler.require(:default, Rails.env)
 
 module ArvadosWorkbench
   class Application < Rails::Application
+
+    require_relative "arvados_config.rb"
+
     # Settings in config/environments/* take precedence over those specified here.
     # Application configuration should go into files in config/initializers
     # -- all .rb files in that directory are automatically loaded.
@@ -71,5 +74,3 @@ module ArvadosWorkbench
     config.assets.paths << Rails.root.join('node_modules')
   end
 end
-
-require File.expand_path('../load_config', __FILE__)
diff --git a/apps/workbench/config/arvados_config.rb b/apps/workbench/config/arvados_config.rb
new file mode 100644 (file)
index 0000000..c0ecfde
--- /dev/null
@@ -0,0 +1,194 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+#
+# Load Arvados configuration from /etc/arvados/config.yml, using defaults
+# from config.default.yml
+#
+# Existing application.yml is migrated into the new config structure.
+# Keys in the legacy application.yml take precedence.
+#
+# Use "bundle exec config:dump" to get the complete active configuration
+#
+# Use "bundle exec config:migrate" to migrate application.yml to
+# config.yml.  After adding the output of config:migrate to
+# /etc/arvados/config.yml, you will be able to delete application.yml.
+
+require 'config_loader'
+require 'config_validators'
+require 'open3'
+
+# Load the defaults, used by config:migrate and fallback loading
+# legacy application.yml
+Open3.popen2("arvados-server", "config-dump", "-config=-") do |stdin, stdout, status_thread|
+  stdin.write("Clusters: {xxxxx: {}}")
+  stdin.close
+  confs = YAML.load(stdout, deserialize_symbols: false)
+  clusterID, clusterConfig = confs["Clusters"].first
+  $arvados_config_defaults = clusterConfig
+  $arvados_config_defaults["ClusterID"] = clusterID
+end
+
+# Load the global config file
+Open3.popen2("arvados-server", "config-dump") do |stdin, stdout, status_thread|
+  confs = YAML.load(stdout, deserialize_symbols: false)
+  if confs && !confs.empty?
+    # config-dump merges defaults with user configuration, so every
+    # key should be set.
+    clusterID, clusterConfig = confs["Clusters"].first
+    $arvados_config_global = clusterConfig
+    $arvados_config_global["ClusterID"] = clusterID
+  else
+    # config-dump failed, assume we will be loading from legacy
+    # application.yml, initialize with defaults.
+    $arvados_config_global = $arvados_config_defaults.deep_dup
+  end
+end
+
+# Now make a copy
+$arvados_config = $arvados_config_global.deep_dup
+
+# Declare all our configuration items.
+arvcfg = ConfigLoader.new
+
+arvcfg.declare_config "ManagementToken", String, :ManagementToken
+arvcfg.declare_config "TLS.Insecure", Boolean, :arvados_insecure_https
+arvcfg.declare_config "Collections.TrustAllContent", Boolean, :trust_all_content
+
+arvcfg.declare_config "Services.Controller.ExternalURL", URI, :arvados_v1_base, ->(cfg, k, v) {
+  u = URI(v)
+  u.path = ""
+  ConfigLoader.set_cfg cfg, "Services.Controller.ExternalURL", u
+}
+
+arvcfg.declare_config "Services.WebShell.ExternalURL", URI, :shell_in_a_box_url, ->(cfg, k, v) {
+  v ||= ""
+  u = URI(v.sub("%{hostname}", "*"))
+  u.path = ""
+  ConfigLoader.set_cfg cfg, "Services.WebShell.ExternalURL", u
+}
+
+arvcfg.declare_config "Services.WebDAV.ExternalURL", URI, :keep_web_url, ->(cfg, k, v) {
+  v ||= ""
+  u = URI(v.sub("%{uuid_or_pdh}", "*"))
+  u.path = ""
+  ConfigLoader.set_cfg cfg, "Services.WebDAV.ExternalURL", u
+}
+
+arvcfg.declare_config "Services.WebDAVDownload.ExternalURL", URI, :keep_web_download_url, ->(cfg, k, v) {
+  v ||= ""
+  u = URI(v.sub("%{uuid_or_pdh}", "*"))
+  u.path = ""
+  ConfigLoader.set_cfg cfg, "Services.WebDAVDownload.ExternalURL", u
+}
+
+arvcfg.declare_config "Services.Composer.ExternalURL", URI, :composer_url
+arvcfg.declare_config "Services.Workbench2.ExternalURL", URI, :workbench2_url
+
+arvcfg.declare_config "Users.AnonymousUserToken", String, :anonymous_user_token
+
+arvcfg.declare_config "Workbench.SecretKeyBase", String, :secret_key_base
+
+arvcfg.declare_config "Workbench.ApplicationMimetypesWithViewIcon", Hash, :application_mimetypes_with_view_icon, ->(cfg, k, v) {
+  mimetypes = {}
+  v.each do |m|
+    mimetypes[m] = {}
+  end
+  ConfigLoader.set_cfg cfg, "Workbench.ApplicationMimetypesWithViewIcon", mimetypes
+}
+
+arvcfg.declare_config "Workbench.RunningJobLogRecordsToFetch", Integer, :running_job_log_records_to_fetch
+arvcfg.declare_config "Workbench.LogViewerMaxBytes", Integer, :log_viewer_max_bytes
+arvcfg.declare_config "Workbench.ProfilingEnabled", Boolean, :profiling_enabled
+arvcfg.declare_config "Workbench.APIResponseCompression", Boolean, :api_response_compression
+arvcfg.declare_config "Workbench.UserProfileFormFields", Hash, :user_profile_form_fields, ->(cfg, k, v) {
+  if !v
+    v = []
+  end
+  entries = {}
+  v.each_with_index do |s,i|
+    entries[s["key"]] = {
+      "Type" => s["type"],
+      "FormFieldTitle" => s["form_field_title"],
+      "FormFieldDescription" => s["form_field_description"],
+      "Required" => s["required"],
+      "Position": i
+    }
+    if s["options"]
+      entries[s["key"]]["Options"] = {}
+      s["options"].each do |o|
+        entries[s["key"]]["Options"][o] = {}
+      end
+    end
+  end
+  ConfigLoader.set_cfg cfg, "Workbench.UserProfileFormFields", entries
+}
+arvcfg.declare_config "Workbench.UserProfileFormMessage", String, :user_profile_form_message
+arvcfg.declare_config "Workbench.Theme", String, :arvados_theme
+arvcfg.declare_config "Workbench.ShowUserNotifications", Boolean, :show_user_notifications
+arvcfg.declare_config "Workbench.ShowUserAgreementInline", Boolean, :show_user_agreement_inline
+arvcfg.declare_config "Workbench.RepositoryCache", String, :repository_cache
+arvcfg.declare_config "Workbench.Repositories", Boolean, :repositories
+arvcfg.declare_config "Workbench.APIClientConnectTimeout", ActiveSupport::Duration, :api_client_connect_timeout
+arvcfg.declare_config "Workbench.APIClientReceiveTimeout", ActiveSupport::Duration, :api_client_receive_timeout
+arvcfg.declare_config "Workbench.APIResponseCompression", Boolean, :api_response_compression
+arvcfg.declare_config "Workbench.SiteName", String, :site_name
+arvcfg.declare_config "Workbench.MultiSiteSearch", String, :multi_site_search, ->(cfg, k, v) {
+  if !v
+    v = ""
+  end
+  ConfigLoader.set_cfg cfg, "Workbench.MultiSiteSearch", v.to_s
+}
+arvcfg.declare_config "Workbench.EnablePublicProjectsPage", Boolean, :enable_public_projects_page
+arvcfg.declare_config "Workbench.EnableGettingStartedPopup", Boolean, :enable_getting_started_popup
+arvcfg.declare_config "Workbench.ArvadosPublicDataDocURL", String, :arvados_public_data_doc_url
+arvcfg.declare_config "Workbench.ArvadosDocsite", String, :arvados_docsite
+arvcfg.declare_config "Workbench.ShowRecentCollectionsOnDashboard", Boolean, :show_recent_collections_on_dashboard
+arvcfg.declare_config "Workbench.ActivationContactLink", String, :activation_contact_link
+arvcfg.declare_config "Workbench.DefaultOpenIdPrefix", String, :default_openid_prefix
+
+arvcfg.declare_config "Mail.SendUserSetupNotificationEmail", Boolean, :send_user_setup_notification_email
+arvcfg.declare_config "Mail.IssueReporterEmailFrom", String, :issue_reporter_email_from
+arvcfg.declare_config "Mail.IssueReporterEmailTo", String, :issue_reporter_email_to
+arvcfg.declare_config "Mail.SupportEmailAddress", String, :support_email_address
+arvcfg.declare_config "Mail.EmailFrom", String, :email_from
+
+application_config = {}
+%w(application.default application).each do |cfgfile|
+  path = "#{::Rails.root.to_s}/config/#{cfgfile}.yml"
+  confs = ConfigLoader.load(path, erb: true)
+  # Ignore empty YAML file:
+  next if confs == false
+  application_config.deep_merge!(confs['common'] || {})
+  application_config.deep_merge!(confs[::Rails.env.to_s] || {})
+end
+
+$remaining_config = arvcfg.migrate_config(application_config, $arvados_config)
+
+# Checks for wrongly typed configuration items, coerces properties
+# into correct types (such as Duration), and optionally raise error
+# for essential configuration that can't be empty.
+arvcfg.coercion_and_check $arvados_config_defaults, check_nonempty: false
+arvcfg.coercion_and_check $arvados_config_global, check_nonempty: false
+arvcfg.coercion_and_check $arvados_config, check_nonempty: true
+
+# * $arvados_config_defaults is the defaults
+# * $arvados_config_global is $arvados_config_defaults merged with the contents of /etc/arvados/config.yml
+# These are used by the rake config: tasks
+#
+# * $arvados_config is $arvados_config_global merged with the migrated contents of application.yml
+# This is what actually gets copied into the Rails configuration object.
+
+ArvadosWorkbench::Application.configure do
+  # Copy into the Rails config object.  This also turns Hash into
+  # OrderedOptions so that application code can use
+  # Rails.configuration.API.Blah instead of
+  # Rails.configuration.API["Blah"]
+  ConfigLoader.copy_into_config $arvados_config, config
+  ConfigLoader.copy_into_config $remaining_config, config
+  secrets.secret_key_base = $arvados_config["Workbench"]["SecretKeyBase"]
+  ConfigValidators.validate_wb2_url_config()
+  ConfigValidators.validate_download_config()
+
+end
diff --git a/apps/workbench/config/load_config.rb b/apps/workbench/config/load_config.rb
deleted file mode 100644 (file)
index 5f0d9ca..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: AGPL-3.0
-
-# This file must be loaded _after_ secret_token.rb if secret_token is
-# defined there instead of in config/application.yml.
-
-$application_config = {}
-
-%w(application.default application).each do |cfgfile|
-  path = "#{::Rails.root.to_s}/config/#{cfgfile}.yml"
-  if File.exist? path
-    yaml = ERB.new(IO.read path).result(binding)
-    confs = YAML.load(yaml, deserialize_symbols: true)
-    $application_config.merge!(confs['common'] || {})
-    $application_config.merge!(confs[::Rails.env.to_s] || {})
-  end
-end
-
-ArvadosWorkbench::Application.configure do
-  nils = []
-  $application_config.each do |k, v|
-    # "foo.bar: baz" --> { config.foo.bar = baz }
-    cfg = config
-    ks = k.split '.'
-    k = ks.pop
-    ks.each do |kk|
-      cfg = cfg.send(kk)
-    end
-    if v.nil? and cfg.respond_to?(k) and !cfg.send(k).nil?
-      # Config is nil in *.yml, but has been set already in
-      # environments/*.rb (or has a Rails default). Don't overwrite
-      # the default/upstream config with nil.
-      #
-      # After config files have been migrated, this mechanism should
-      # be removed.
-      Rails.logger.warn <<EOS
-DEPRECATED: Inheriting config.#{ks.join '.'} from Rails config.
-            Please move this config into config/application.yml.
-EOS
-    elsif v.nil?
-      # Config variables are not allowed to be nil. Make a "naughty"
-      # list, and present it below.
-      nils << k
-    else
-      cfg.send "#{k}=", v
-    end
-  end
-  if !nils.empty? and not ::Rails.groups.include?('assets')
-    raise <<EOS
-#{::Rails.groups.include?('assets')}
-Refusing to start in #{::Rails.env.to_s} mode with missing configuration.
-
-The following configuration settings must be specified in
-config/application.yml:
-* #{nils.join "\n* "}
-
-EOS
-  end
-  # Refuse to start if keep-web isn't configured
-  if not (config.keep_web_url or config.keep_web_download_url) and not ::Rails.groups.include?('assets')
-    raise <<EOS
-Refusing to start in #{::Rails.env.to_s} mode with missing configuration.
-
-Keep-web service must be configured in config/application.yml:
-* keep_web_url
-* keep_web_download_url
-
-EOS
-  end
-end
index 22ec1ba14c6dad9a83cc3594aa0353f835331e91..48913a14d7fd1929b1ada72fb94cba1ad78be7bf 100644 (file)
@@ -4,9 +4,9 @@
 
 case "$TARGET" in
     centos*)
-        fpm_depends+=(git)
+        fpm_depends+=(git arvados-server)
         ;;
     debian* | ubuntu*)
-        fpm_depends+=(git g++)
+        fpm_depends+=(git g++ arvados-server)
         ;;
 esac
diff --git a/apps/workbench/lib/config_loader.rb b/apps/workbench/lib/config_loader.rb
new file mode 100644 (file)
index 0000000..730e468
--- /dev/null
@@ -0,0 +1,243 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+module Psych
+  module Visitors
+    class YAMLTree < Psych::Visitors::Visitor
+      def visit_ActiveSupport_Duration o
+        seconds = o.to_i
+        outstr = ""
+        if seconds / 3600 > 0
+          outstr += "#{seconds / 3600}h"
+          seconds = seconds % 3600
+        end
+        if seconds / 60 > 0
+          outstr += "#{seconds / 60}m"
+          seconds = seconds % 60
+        end
+        if seconds > 0
+          outstr += "#{seconds}s"
+        end
+        if outstr == ""
+          outstr = "0s"
+        end
+        @emitter.scalar outstr, nil, nil, true, false, Nodes::Scalar::ANY
+      end
+
+      def visit_URI_Generic o
+        @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
+      end
+
+      def visit_URI_HTTP o
+        @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
+      end
+
+      def visit_Pathname o
+        @emitter.scalar o.to_s, nil, nil, true, false, Nodes::Scalar::ANY
+      end
+    end
+  end
+end
+
+
+module Boolean; end
+class TrueClass; include Boolean; end
+class FalseClass; include Boolean; end
+
+class NonemptyString < String
+end
+
+class ConfigLoader
+  def initialize
+    @config_migrate_map = {}
+    @config_types = {}
+  end
+
+  def declare_config(assign_to, configtype, migrate_from=nil, migrate_fn=nil)
+    if migrate_from
+      @config_migrate_map[migrate_from] = migrate_fn || ->(cfg, k, v) {
+        ConfigLoader.set_cfg cfg, assign_to, v
+      }
+    end
+    @config_types[assign_to] = configtype
+  end
+
+
+  def migrate_config from_config, to_config
+    remainders = {}
+    from_config.each do |k, v|
+      if @config_migrate_map[k.to_sym]
+        begin
+          @config_migrate_map[k.to_sym].call to_config, k, v
+        rescue => e
+          raise "Error migrating '#{k}: #{v}' got error #{e}"
+        end
+      else
+        remainders[k] = v
+      end
+    end
+    remainders
+  end
+
+  def coercion_and_check check_cfg, check_nonempty: true
+    @config_types.each do |cfgkey, cfgtype|
+      begin
+        cfg = check_cfg
+        k = cfgkey
+        ks = k.split '.'
+        k = ks.pop
+        ks.each do |kk|
+          cfg = cfg[kk]
+          if cfg.nil?
+            break
+          end
+        end
+
+        if cfg.nil?
+          raise "missing #{cfgkey}"
+        end
+
+        if cfgtype == String and !cfg[k]
+          cfg[k] = ""
+        end
+
+        if cfgtype == String and cfg[k].is_a? Symbol
+          cfg[k] = cfg[k].to_s
+        end
+
+        if cfgtype == Pathname and cfg[k].is_a? String
+
+          if cfg[k] == ""
+            cfg[k] = Pathname.new("")
+          else
+            cfg[k] = Pathname.new(cfg[k])
+            if !cfg[k].exist?
+              raise "#{cfgkey} path #{cfg[k]} does not exist"
+            end
+          end
+        end
+
+        if cfgtype == NonemptyString
+          if (!cfg[k] || cfg[k] == "") && check_nonempty
+            raise "#{cfgkey} cannot be empty"
+          end
+          if cfg[k].is_a? String
+            next
+          end
+        end
+
+        if cfgtype == ActiveSupport::Duration
+          if cfg[k].is_a? Integer
+            cfg[k] = cfg[k].seconds
+          elsif cfg[k].is_a? String
+            cfg[k] = ConfigLoader.parse_duration(cfg[k], cfgkey: cfgkey)
+          end
+        end
+
+        if cfgtype == URI
+          if cfg[k]
+            cfg[k] = URI(cfg[k])
+          else
+            cfg[k] = URI("")
+          end
+        end
+
+        if cfgtype == Integer && cfg[k].is_a?(String)
+          v = cfg[k].sub(/B\s*$/, '')
+          if mt = /(-?\d*\.?\d+)\s*([KMGTPE]i?)$/.match(v)
+            if mt[1].index('.')
+              v = mt[1].to_f
+            else
+              v = mt[1].to_i
+            end
+            cfg[k] = v * {
+              'K' => 1000,
+              'Ki' => 1 << 10,
+              'M' => 1000000,
+              'Mi' => 1 << 20,
+             "G" =>  1000000000,
+             "Gi" => 1 << 30,
+             "T" =>  1000000000000,
+             "Ti" => 1 << 40,
+             "P" =>  1000000000000000,
+             "Pi" => 1 << 50,
+             "E" =>  1000000000000000000,
+             "Ei" => 1 << 60,
+            }[mt[2]]
+          end
+        end
+
+      rescue => e
+        raise "#{cfgkey} expected #{cfgtype} but '#{cfg[k]}' got error #{e}"
+      end
+
+      if !cfg[k].is_a? cfgtype
+        raise "#{cfgkey} expected #{cfgtype} but was #{cfg[k].class}"
+      end
+    end
+  end
+
+  def self.set_cfg cfg, k, v
+    # "foo.bar = baz" --> { cfg["foo"]["bar"] = baz }
+    ks = k.split '.'
+    k = ks.pop
+    ks.each do |kk|
+      cfg = cfg[kk]
+      if cfg.nil?
+        break
+      end
+    end
+    if !cfg.nil?
+      cfg[k] = v
+    end
+  end
+
+  def self.parse_duration durstr, cfgkey:
+    duration_re = /-?(\d+(\.\d+)?)(s|m|h)/
+    dursec = 0
+    while durstr != ""
+      mt = duration_re.match durstr
+      if !mt
+        raise "#{cfgkey} not a valid duration: '#{durstr}', accepted suffixes are s, m, h"
+      end
+      multiplier = {s: 1, m: 60, h: 3600}
+      dursec += (Float(mt[1]) * multiplier[mt[3].to_sym])
+      durstr = durstr[mt[0].length..-1]
+    end
+    return dursec.seconds
+  end
+
+  def self.copy_into_config src, dst
+    src.each do |k, v|
+      dst.send "#{k}=", self.to_OrderedOptions(v)
+    end
+  end
+
+  def self.to_OrderedOptions confs
+    if confs.is_a? Hash
+      opts = ActiveSupport::OrderedOptions.new
+      confs.each do |k,v|
+        opts[k] = self.to_OrderedOptions(v)
+      end
+      opts
+    elsif confs.is_a? Array
+      confs.map { |v| self.to_OrderedOptions v }
+    else
+      confs
+    end
+  end
+
+  def self.load path, erb: false
+    if File.exist? path
+      yaml = IO.read path
+      if erb
+        yaml = ERB.new(yaml).result(binding)
+      end
+      YAML.load(yaml, deserialize_symbols: false)
+    else
+      {}
+    end
+  end
+
+end
index ec769168c28ac2d6cdfb6ff77c5221c1bf557038..804e3e397015bd9706d978c3067f805645a88aeb 100644 (file)
@@ -5,24 +5,22 @@
 require 'uri'
 
 module ConfigValidators
-    def validate_wb2_url_config
-        if Rails.configuration.workbench2_url
-            begin
-                if !URI.parse(Rails.configuration.workbench2_url).is_a?(URI::HTTP)
-                    Rails.logger.warn("workbench2_url config is not an HTTP URL: #{Rails.configuration.workbench2_url}")
-                    Rails.configuration.workbench2_url = false
-                elsif /.*[\/]{2,}$/.match(Rails.configuration.workbench2_url)
-                    Rails.logger.warn("workbench2_url config shouldn't have multiple trailing slashes: #{Rails.configuration.workbench2_url}")
-                    Rails.configuration.workbench2_url = false
-                else
-                    return true
-                end
-            rescue URI::InvalidURIError
-                Rails.logger.warn("workbench2_url config invalid URL: #{Rails.configuration.workbench2_url}")
-                Rails.configuration.workbench2_url = false
-            end
-        end
-        return false
+  def self.validate_wb2_url_config
+    if Rails.configuration.Services.Workbench2.ExternalURL != URI("")
+      if !Rails.configuration.Services.Workbench2.ExternalURL.is_a?(URI::HTTP)
+        raise "workbench2_url config is not an HTTP URL: #{Rails.configuration.Services.Workbench2.ExternalURL}"
+      elsif /.*[\/]{2,}$/.match(Rails.configuration.Services.Workbench2.ExternalURL.to_s)
+        raise "workbench2_url config shouldn't have multiple trailing slashes: #{Rails.configuration.Services.Workbench2.ExternalURL}"
+      else
+        return true
+      end
     end
-end
+    return false
+  end
 
+  def self.validate_download_config
+    if Rails.configuration.Services.WebDAV.ExternalURL == URI("") and Rails.configuration.Services.WebDAVDownload.ExternalURL == URI("")
+      raise "Keep-web service must be configured in Services.WebDAV and/or Services.WebDAVDownload"
+    end
+  end
+end
diff --git a/apps/workbench/lib/tasks/config.rake b/apps/workbench/lib/tasks/config.rake
new file mode 100644 (file)
index 0000000..6067208
--- /dev/null
@@ -0,0 +1,56 @@
+# Copyright (C) The Arvados Authors. All rights reserved.
+#
+# SPDX-License-Identifier: AGPL-3.0
+
+def diff_hash base, final
+  diffed = {}
+  base.each do |k,v|
+    bk = base[k]
+    fk = final[k]
+    if bk.is_a? Hash
+      d = diff_hash bk, fk
+      if d.length > 0
+        diffed[k] = d
+      end
+    else
+      if bk.to_yaml != fk.to_yaml
+        diffed[k] = fk
+      end
+    end
+  end
+  diffed
+end
+
+namespace :config do
+  desc 'Print items that differ between legacy application.yml and system config.yml'
+  task diff: :environment do
+    diffed = diff_hash $arvados_config_global, $arvados_config
+    cfg = { "Clusters" => {}}
+    cfg["Clusters"][$arvados_config["ClusterID"]] = diffed.select {|k,v| k != "ClusterID"}
+    if cfg["Clusters"][$arvados_config["ClusterID"]].empty?
+      puts "No migrations required for /etc/arvados/config.yml"
+    else
+      puts cfg.to_yaml
+    end
+  end
+
+  desc 'Print config.yml after merging with legacy application.yml'
+  task migrate: :environment do
+    diffed = diff_hash $arvados_config_defaults, $arvados_config
+    cfg = { "Clusters" => {}}
+    cfg["Clusters"][$arvados_config["ClusterID"]] = diffed.select {|k,v| k != "ClusterID"}
+    puts cfg.to_yaml
+  end
+
+  desc 'Print configuration as accessed through Rails.configuration'
+  task dump: :environment do
+    combined = $arvados_config.deep_dup
+    combined.update $remaining_config
+    puts combined.to_yaml
+  end
+
+  desc 'Legacy config check task -- it is a noop now'
+  task check: :environment do
+    # This exists so that build/rails-package-scripts/postinst.sh doesn't fail.
+  end
+end
diff --git a/apps/workbench/lib/tasks/config_check.rake b/apps/workbench/lib/tasks/config_check.rake
deleted file mode 100644 (file)
index 9fd5435..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: AGPL-3.0
-
-namespace :config do
-  desc 'Ensure site configuration has all required settings'
-  task check: :environment do
-    $application_config.sort.each do |k, v|
-      if ENV.has_key?('QUIET') then
-        # Make sure we still check for the variable to exist
-        eval("Rails.configuration.#{k}")
-      else
-        if /(password|secret)/.match(k) then
-          # Make sure we still check for the variable to exist, but don't print the value
-          eval("Rails.configuration.#{k}")
-          $stderr.puts "%-32s %s" % [k, '*********']
-        else
-          $stderr.puts "%-32s %s" % [k, eval("Rails.configuration.#{k}")]
-        end
-      end
-    end
-  end
-end
diff --git a/apps/workbench/lib/tasks/config_dump.rake b/apps/workbench/lib/tasks/config_dump.rake
deleted file mode 100644 (file)
index ed34960..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) The Arvados Authors. All rights reserved.
-#
-# SPDX-License-Identifier: AGPL-3.0
-
-namespace :config do
-  desc 'Show site configuration'
-  task dump: :environment do
-    puts $application_config.to_yaml
-  end
-end
index 86aa304e472324f992b7e72b5b1e7d27580f38e3..fbbffe87cb875e93528f84c3f29f3908ca996946 100644 (file)
@@ -173,7 +173,7 @@ class ActionsControllerTest < ActionController::TestCase
     ['pipeline_templates', 'pipeline_template_in_publicly_accessible_project'],
   ].each do |dm, fixture|
     test "access show method for public #{dm} and expect to see page" do
-      Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+      Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
       get(:show, params: {uuid: api_fixture(dm)[fixture]['uuid']})
       assert_response :redirect
       if dm == 'groups'
@@ -193,7 +193,7 @@ class ActionsControllerTest < ActionController::TestCase
     ['traits', 'owned_by_aproject_with_no_name', :redirect],
   ].each do |dm, fixture, expected|
     test "access show method for non-public #{dm} and expect #{expected}" do
-      Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+      Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
       get(:show, params: {uuid: api_fixture(dm)[fixture]['uuid']})
       assert_response expected
       if expected == 404
index b908c46def39664abb4b1715cba6b4f996a1caab..72c3e0ab0cfe4f30f43d29f856ab5ef43c375e78 100644 (file)
@@ -346,7 +346,7 @@ class ApplicationControllerTest < ActionController::TestCase
       true
     end.returns fake_api_response('{}', 200, {})
 
-    Rails.configuration.anonymous_user_token =
+    Rails.configuration.Users.AnonymousUserToken =
       api_fixture("api_client_authorizations", "anonymous", "api_token")
     @controller = ProjectsController.new
     test_uuid = "zzzzz-j7d0g-zzzzzzzzzzzzzzz"
@@ -374,7 +374,7 @@ class ApplicationControllerTest < ActionController::TestCase
   ].each do |css_selector|
     test "login link at #{css_selector.inspect} includes return_to param" do
       # Without an anonymous token, we're immediately redirected to login.
-      Rails.configuration.anonymous_user_token =
+      Rails.configuration.Users.AnonymousUserToken =
         api_fixture("api_client_authorizations", "anonymous", "api_token")
       @controller = ProjectsController.new
       test_uuid = "zzzzz-j7d0g-zzzzzzzzzzzzzzz"
@@ -393,17 +393,17 @@ class ApplicationControllerTest < ActionController::TestCase
     # We're really testing ApplicationController's render_exception.
     # Our primary concern is that it doesn't raise an error and
     # return 500.
-    orig_api_server = Rails.configuration.arvados_v1_base
+    orig_api_server = Rails.configuration.Services.Controller.ExternalURL
     begin
       # The URL should look valid in all respects, and avoid talking over a
       # network.  100::/64 is the IPv6 discard prefix, so it's perfect.
-      Rails.configuration.arvados_v1_base = "https://[100::f]:1/"
+      Rails.configuration.Services.Controller.ExternalURL = "https://[100::f]:1/"
       @controller = NodesController.new
       get(:index, params: {}, session: session_for(:active))
       assert_includes(405..422, @response.code.to_i,
                       "bad response code when API server is unreachable")
     ensure
-      Rails.configuration.arvados_v1_base = orig_api_server
+      Rails.configuration.Services.Controller.ExternalURL = orig_api_server
     end
   end
 
@@ -421,9 +421,9 @@ class ApplicationControllerTest < ActionController::TestCase
   ].each do |controller, fixture, anon_config=true|
     test "#{controller} show method with anonymous config #{anon_config ? '' : 'not '}enabled" do
       if anon_config
-        Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+        Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
       else
-        Rails.configuration.anonymous_user_token = false
+        Rails.configuration.Users.AnonymousUserToken = ""
       end
 
       @controller = controller
@@ -449,7 +449,7 @@ class ApplicationControllerTest < ActionController::TestCase
     false,
   ].each do |config|
     test "invoke show with include_accept_encoding_header config #{config}" do
-      Rails.configuration.include_accept_encoding_header_in_api_requests = config
+      Rails.configuration.APIResponseCompression = config
 
       @controller = CollectionsController.new
       get(:show, params: {id: api_fixture('collections')['foo_file']['uuid']}, session: session_for(:admin))
index 88287cd3f3d1cd0b5e65ed980b4c58b6ce4b13dd..4fce54a8ab4e2b042be8c5b25e75cc80bf97aff0 100644 (file)
@@ -15,11 +15,11 @@ class CollectionsControllerTest < ActionController::TestCase
   NONEXISTENT_COLLECTION = "ffffffffffffffffffffffffffffffff+0"
 
   def config_anonymous enable
-    Rails.configuration.anonymous_user_token =
+    Rails.configuration.Users.AnonymousUserToken =
       if enable
         api_token('anonymous')
       else
-        false
+        ""
       end
   end
 
@@ -471,9 +471,9 @@ class CollectionsControllerTest < ActionController::TestCase
     assert_not_includes @response.body, '<a href="#Upload"'
   end
 
-  def setup_for_keep_web cfg='https://%{uuid_or_pdh}.example', dl_cfg=false
-    Rails.configuration.keep_web_url = cfg
-    Rails.configuration.keep_web_download_url = dl_cfg
+  def setup_for_keep_web cfg='https://*.example', dl_cfg=""
+    Rails.configuration.Services.WebDAV.ExternalURL = URI(cfg)
+    Rails.configuration.Services.WebDAVDownload.ExternalURL = URI(dl_cfg)
   end
 
   %w(uuid portable_data_hash).each do |id_type|
@@ -522,8 +522,8 @@ class CollectionsControllerTest < ActionController::TestCase
     end
 
     test "Redirect to keep_web_download_url via #{id_type}" do
-      setup_for_keep_web('https://collections.example/c=%{uuid_or_pdh}',
-                         'https://download.example/c=%{uuid_or_pdh}')
+      setup_for_keep_web('https://collections.example',
+                         'https://download.example')
       tok = api_token('active')
       id = api_fixture('collections')['w_a_z_file'][id_type]
       get :show_file, params: {uuid: id, file: "w a z"}, session: session_for(:active)
@@ -532,9 +532,9 @@ class CollectionsControllerTest < ActionController::TestCase
     end
 
     test "Redirect to keep_web_url via #{id_type} when trust_all_content enabled" do
-      Rails.configuration.trust_all_content = true
-      setup_for_keep_web('https://collections.example/c=%{uuid_or_pdh}',
-                         'https://download.example/c=%{uuid_or_pdh}')
+      Rails.configuration.Workbench.TrustAllContent = true
+      setup_for_keep_web('https://collections.example',
+                         'https://download.example')
       tok = api_token('active')
       id = api_fixture('collections')['w_a_z_file'][id_type]
       get :show_file, params: {uuid: id, file: "w a z"}, session: session_for(:active)
@@ -554,8 +554,8 @@ class CollectionsControllerTest < ActionController::TestCase
 
     test "Redirect download to keep_web_download_url, anon #{anon}" do
       config_anonymous anon
-      setup_for_keep_web('https://collections.example/c=%{uuid_or_pdh}',
-                         'https://download.example/c=%{uuid_or_pdh}')
+      setup_for_keep_web('https://collections.example/',
+                         'https://download.example/')
       tok = api_token('active')
       id = api_fixture('collections')['public_text_file']['uuid']
       get :show_file, params: {
@@ -575,7 +575,7 @@ class CollectionsControllerTest < ActionController::TestCase
   test "Error if file is impossible to retrieve from keep_web_url" do
     # Cannot pass a session token using a single-origin keep-web URL,
     # cannot read this collection without a session token.
-    setup_for_keep_web 'https://collections.example/c=%{uuid_or_pdh}', false
+    setup_for_keep_web 'https://collections.example/', ""
     id = api_fixture('collections')['w_a_z_file']['uuid']
     get :show_file, params: {uuid: id, file: "w a z"}, session: session_for(:active)
     assert_response 422
@@ -583,8 +583,8 @@ class CollectionsControllerTest < ActionController::TestCase
 
   [false, true].each do |trust_all_content|
     test "Redirect preview to keep_web_download_url when preview is disabled and trust_all_content is #{trust_all_content}" do
-      Rails.configuration.trust_all_content = trust_all_content
-      setup_for_keep_web false, 'https://download.example/c=%{uuid_or_pdh}'
+      Rails.configuration.Workbench.TrustAllContent = trust_all_content
+      setup_for_keep_web "", 'https://download.example/'
       tok = api_token('active')
       id = api_fixture('collections')['w_a_z_file']['uuid']
       get :show_file, params: {uuid: id, file: "w a z"}, session: session_for(:active)
index 556b958d00a8f0fe50c1a9af9d81b62c2eeb1771..9144564c912bb96735b4ce967e06b2e1795ec30e 100644 (file)
@@ -59,7 +59,7 @@ class DisabledApiTest < ActionController::TestCase
     test "project tabs as user #{user} when pipeline related index APIs are disabled" do
       @controller = ProjectsController.new
 
-      Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+      Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
 
       dd = ArvadosApiClient.new_or_current.discovery.deep_dup
       dd[:resources][:pipeline_templates][:methods].delete(:index)
index 09a6950cead6fad12ce20262c3eda4a6d978d91c..750c779ae7ca2d537911feabfa25484b85338443 100644 (file)
@@ -240,14 +240,14 @@ class ProjectsControllerTest < ActionController::TestCase
   end
 
   test "visit non-public project as anonymous when anonymous browsing is enabled and expect page not found" do
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
     get(:show, params: {id: api_fixture('groups')['aproject']['uuid']})
     assert_response 404
     assert_match(/log ?in/i, @response.body)
   end
 
   test "visit home page as anonymous when anonymous browsing is enabled and expect login" do
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
     get(:index)
     assert_response :redirect
     assert_match /\/users\/welcome/, @response.redirect_url
@@ -258,7 +258,7 @@ class ProjectsControllerTest < ActionController::TestCase
     :active,
   ].each do |user|
     test "visit public projects page when anon config is enabled, as user #{user}, and expect page" do
-      Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+      Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
 
       if user
         get :public, params: {}, session: session_for(user)
@@ -276,22 +276,22 @@ class ProjectsControllerTest < ActionController::TestCase
   end
 
   test "visit public projects page when anon config is not enabled as active user and expect 404" do
-    Rails.configuration.anonymous_user_token = nil
-    Rails.configuration.enable_public_projects_page = false
+    Rails.configuration.Users.AnonymousUserToken = ""
+    Rails.configuration.Workbench.EnablePublicProjectsPage = false
     get :public, params: {}, session: session_for(:active)
     assert_response 404
   end
 
   test "visit public projects page when anon config is enabled but public projects page is disabled as active user and expect 404" do
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
-    Rails.configuration.enable_public_projects_page = false
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Workbench.EnablePublicProjectsPage = false
     get :public, params: {}, session: session_for(:active)
     assert_response 404
   end
 
   test "visit public projects page when anon config is not enabled as anonymous and expect login page" do
-    Rails.configuration.anonymous_user_token = nil
-    Rails.configuration.enable_public_projects_page = false
+    Rails.configuration.Users.AnonymousUserToken = ""
+    Rails.configuration.Workbench.EnablePublicProjectsPage = false
     get :public
     assert_response :redirect
     assert_match /\/users\/welcome/, @response.redirect_url
@@ -299,8 +299,8 @@ class ProjectsControllerTest < ActionController::TestCase
   end
 
   test "visit public projects page when anon config is enabled and public projects page is disabled and expect login page" do
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
-    Rails.configuration.enable_public_projects_page = false
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Workbench.EnablePublicProjectsPage = false
     get :index
     assert_response :redirect
     assert_match /\/users\/welcome/, @response.redirect_url
@@ -308,7 +308,7 @@ class ProjectsControllerTest < ActionController::TestCase
   end
 
   test "visit public projects page when anon config is not enabled and public projects page is enabled and expect login page" do
-    Rails.configuration.enable_public_projects_page = true
+    Rails.configuration.Workbench.EnablePublicProjectsPage = true
     get :index
     assert_response :redirect
     assert_match /\/users\/welcome/, @response.redirect_url
@@ -501,7 +501,7 @@ EOT
   end
 
   test "visit a public project and verify the public projects page link exists" do
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
     uuid = api_fixture('groups')['anonymously_accessible_project']['uuid']
     get :show, params: {id: uuid}
     project = assigns(:object)
index 57b8705963d752e41123fcb094f1f4505a8a3862..742fe6b13e1c3ed5b0a4a7ff7e720bc8f6874565 100644 (file)
@@ -14,7 +14,7 @@ class UsersControllerTest < ActionController::TestCase
   test "ignore previously valid token (for deleted user), don't crash" do
     get :activity, params: {}, session: session_for(:valid_token_deleted_user)
     assert_response :redirect
-    assert_match /^#{Rails.configuration.arvados_login_base}/, @response.redirect_url
+    assert_match /^#{Rails.configuration.Services.Controller.ExternalURL}\/login/, @response.redirect_url
     assert_nil assigns(:my_jobs)
     assert_nil assigns(:my_ssh_keys)
   end
@@ -24,7 +24,7 @@ class UsersControllerTest < ActionController::TestCase
       id: api_fixture('users')['active']['uuid']
     }, session: session_for(:expired_trustedclient)
     assert_response :redirect
-    assert_match /^#{Rails.configuration.arvados_login_base}/, @response.redirect_url
+    assert_match /^#{Rails.configuration.Services.Controller.ExternalURL}\/login/, @response.redirect_url
     assert_nil assigns(:my_jobs)
     assert_nil assigns(:my_ssh_keys)
   end
index 8d772b087f54f02d0f2172d6820bec3823d36baf..c414f8a7ad76e4a5c3844c0ce61a088fe5fcd403 100644 (file)
@@ -14,7 +14,7 @@ class AnonymousAccessTest < ActionDispatch::IntegrationTest
 
   setup do
     need_javascript
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
   end
 
   PUBLIC_PROJECT = "/projects/#{api_fixture('groups')['anonymously_accessible_project']['uuid']}"
@@ -35,7 +35,7 @@ class AnonymousAccessTest < ActionDispatch::IntegrationTest
         assert_text 'indicate that you have read and accepted the user agreement'
       end
       within('.navbar-fixed-top') do
-        assert_selector 'a', text: Rails.configuration.site_name.downcase
+        assert_selector 'a', text: Rails.configuration.Workbench.SiteName.downcase
         assert(page.has_link?("notifications-menu"), 'no user menu')
         page.find("#notifications-menu").click
         within('.dropdown-menu') do
@@ -45,8 +45,8 @@ class AnonymousAccessTest < ActionDispatch::IntegrationTest
     else  # anonymous
       assert_text 'Unrestricted public data'
       within('.navbar-fixed-top') do
-        assert_text Rails.configuration.site_name.downcase
-        assert_no_selector 'a', text: Rails.configuration.site_name.downcase
+        assert_text Rails.configuration.Workbench.SiteName.downcase
+        assert_no_selector 'a', text: Rails.configuration.Workbench.SiteName.downcase
         assert_selector 'a', text: 'Log in'
         assert_selector 'a', text: 'Browse public projects'
       end
index 51c3720985a85e0fbfd3ebd60ff1473134af78ab..505767814a3c4612e95578886121bdf5d2c7a457 100644 (file)
@@ -16,13 +16,13 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
   end
 
   def verify_homepage user, invited, has_profile
-    profile_config = Rails.configuration.user_profile_form_fields
+    profile_config = Rails.configuration.Workbench.UserProfileFormFields
 
     if !user
       assert page.has_text?('Please log in'), 'Not found text - Please log in'
       assert page.has_text?('The "Log in" button below will show you a Google sign-in page'), 'Not found text - google sign in page'
       assert page.has_no_text?('My projects'), 'Found text - My projects'
-      assert page.has_link?("Log in to #{Rails.configuration.site_name}"), 'Not found text - log in to'
+      assert page.has_link?("Log in to #{Rails.configuration.Workbench.SiteName}"), 'Not found text - log in to'
     elsif user['is_active']
       if profile_config && !has_profile
         assert page.has_text?('Save profile'), 'No text - Save profile'
@@ -42,12 +42,12 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
 
     within('.navbar-fixed-top') do
       if !user
-        assert_text Rails.configuration.site_name.downcase
-        assert_no_selector 'a', text: Rails.configuration.site_name.downcase
+        assert_text Rails.configuration.Workbench.SiteName.downcase
+        assert_no_selector 'a', text: Rails.configuration.Workbench.SiteName.downcase
         assert page.has_link?('Log in'), 'Not found link - Log in'
       else
         # my account menu
-        assert_selector 'a', text: Rails.configuration.site_name.downcase
+        assert_selector 'a', text: Rails.configuration.Workbench.SiteName.downcase
         assert(page.has_link?("notifications-menu"), 'no user menu')
         page.find("#notifications-menu").click
         within('.dropdown-menu') do
@@ -142,7 +142,7 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
   end
 
   [
-    [false, false],
+    ["", false],
     ['http://wb2.example.org//', false],
     ['ftp://wb2.example.org', false],
     ['wb2.example.org', false],
@@ -152,8 +152,13 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
     ['https://wb2.example.org/', true],
   ].each do |wb2_url_config, wb2_menu_appear|
     test "workbench2_url=#{wb2_url_config} should#{wb2_menu_appear ? '' : ' not'} show WB2 menu" do
-      Rails.configuration.workbench2_url = wb2_url_config
-      assert_equal wb2_menu_appear, ConfigValidators::validate_wb2_url_config()
+      Rails.configuration.Services.Workbench2.ExternalURL = URI(wb2_url_config)
+      if !wb2_menu_appear and !wb2_url_config.empty?
+        assert_raises RuntimeError do
+          ConfigValidators.validate_wb2_url_config()
+        end
+        Rails.configuration.Services.Workbench2.ExternalURL = URI("")
+      end
 
       visit page_with_token('active')
       within('.navbar-fixed-top') do
@@ -170,7 +175,7 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
     ['active_with_prefs_profile_no_getting_started_shown', false],
   ].each do |token, getting_started_shown|
     test "getting started help menu item #{getting_started_shown}" do
-      Rails.configuration.enable_getting_started_popup = true
+      Rails.configuration.Workbench.EnableGettingStartedPopup = true
 
       visit page_with_token(token)
 
@@ -213,7 +218,7 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
   end
 
   test "test arvados_public_data_doc_url config unset" do
-    Rails.configuration.arvados_public_data_doc_url = false
+    Rails.configuration.Workbench.ArvadosPublicDataDocURL = ""
 
     visit page_with_token('active')
     within '.navbar-fixed-top' do
@@ -231,7 +236,7 @@ class ApplicationLayoutTest < ActionDispatch::IntegrationTest
   end
 
   test "no SSH public key notification when shell_in_a_box_url is configured" do
-    Rails.configuration.shell_in_a_box_url = 'example.com'
+    Rails.configuration.Services.WebShell.ExternalURL = URI('http://example.com')
     visit page_with_token('job_reader')
     click_link 'notifications-menu'
     assert_no_selector 'a', text:'Click here to set up an SSH public key for use with Arvados.'
index 407458b62bd4c3557e8c21e20b4bde201cfda1e3..b19c00dae99c9b8839ff904dec648e45833149e2 100644 (file)
@@ -42,7 +42,7 @@ class DownloadTest < ActionDispatch::IntegrationTest
     end
 
     test "preview anonymous content from keep-web by #{id_type}" do
-      Rails.configuration.anonymous_user_token =
+      Rails.configuration.Users.AnonymousUserToken =
         api_fixture('api_client_authorizations')['anonymous']['api_token']
       uuid_or_pdh =
         api_fixture('collections')['public_text_file'][id_type]
@@ -55,7 +55,7 @@ class DownloadTest < ActionDispatch::IntegrationTest
     end
 
     test "download anonymous content from keep-web by #{id_type}" do
-      Rails.configuration.anonymous_user_token =
+      Rails.configuration.Users.AnonymousUserToken =
         api_fixture('api_client_authorizations')['anonymous']['api_token']
       uuid_or_pdh =
         api_fixture('collections')['public_text_file'][id_type]
index 81d4bbbaa1735dd98ce2ccbb7a54b25b8675a43b..86d5902ff5b1ef11ec62d6a0c8219225d5b71c45 100644 (file)
@@ -72,15 +72,15 @@ class ErrorsTest < ActionDispatch::IntegrationTest
 
   test "API error page has Report problem button" do
     # point to a bad api server url to generate fiddlesticks error
-    original_arvados_v1_base = Rails.configuration.arvados_v1_base
-    Rails.configuration.arvados_v1_base = "https://[::1]:1/"
+    original_arvados_v1_base = Rails.configuration.Services.Controller.ExternalURL
+    Rails.configuration.Services.Controller.ExternalURL = URI("https://[::1]:1/")
 
     visit page_with_token("active")
 
     assert_text 'fiddlesticks'
 
     # reset api server base config to let the popup rendering to work
-    Rails.configuration.arvados_v1_base = original_arvados_v1_base
+    Rails.configuration.Services.Controller.ExternalURL = original_arvados_v1_base
 
     click_link 'Report problem'
 
index bf48d88cf3f754455d9902727c3b91f4806672d1..b54a31380ce93f9cbb0ae726a47a636e4ed57981 100644 (file)
@@ -44,7 +44,7 @@ class JobsTest < ActionDispatch::IntegrationTest
     use_keep_web_config
 
     # This config will be restored during teardown by ../test_helper.rb:
-    Rails.configuration.log_viewer_max_bytes = 100
+    Rails.configuration.Workbench.LogViewerMaxBytes = 100
 
     logdata = fakepipe_with_log_data.read
     job_uuid = api_fixture('jobs')['running']['uuid']
index 9c22f5a7721a7b388111ecdac8133a7a0e9302e7..53c7ec85532be6022d2dc89b35e09def57653f2b 100644 (file)
@@ -10,6 +10,10 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
     need_javascript
   end
 
+  teardown do
+    Rails.configuration.testing_override_login_url = false
+  end
+
   def start_sso_stub token
     port = available_port('sso_stub')
 
@@ -38,8 +42,7 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
 
   test "Add another login to this account" do
     visit page_with_token('active_trustedclient')
-    stub = start_sso_stub(api_fixture('api_client_authorizations')['project_viewer_trustedclient']['api_token'])
-    Rails.configuration.arvados_login_base = stub + "login"
+    Rails.configuration.testing_override_login_url = start_sso_stub(api_fixture('api_client_authorizations')['project_viewer_trustedclient']['api_token'])
 
     find("#notifications-menu").click
     assert_text "active-user@arvados.local"
@@ -58,8 +61,7 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
 
   test "Use this login to access another account" do
     visit page_with_token('project_viewer_trustedclient')
-    stub = start_sso_stub(api_fixture('api_client_authorizations')['active_trustedclient']['api_token'])
-    Rails.configuration.arvados_login_base = stub + "login"
+    Rails.configuration.testing_override_login_url = start_sso_stub(api_fixture('api_client_authorizations')['active_trustedclient']['api_token'])
 
     find("#notifications-menu").click
     assert_text "project-viewer@arvados.local"
@@ -78,8 +80,7 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
 
   test "Link login of inactive user to this account" do
     visit page_with_token('active_trustedclient')
-    stub = start_sso_stub(api_fixture('api_client_authorizations')['inactive_uninvited_trustedclient']['api_token'])
-    Rails.configuration.arvados_login_base = stub + "login"
+    Rails.configuration.testing_override_login_url = start_sso_stub(api_fixture('api_client_authorizations')['inactive_uninvited_trustedclient']['api_token'])
 
     find("#notifications-menu").click
     assert_text "active-user@arvados.local"
@@ -98,8 +99,7 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
 
   test "Cannot link to inactive user" do
     visit page_with_token('active_trustedclient')
-    stub = start_sso_stub(api_fixture('api_client_authorizations')['inactive_uninvited_trustedclient']['api_token'])
-    Rails.configuration.arvados_login_base = stub + "login"
+    Rails.configuration.testing_override_login_url = start_sso_stub(api_fixture('api_client_authorizations')['inactive_uninvited_trustedclient']['api_token'])
 
     find("#notifications-menu").click
     assert_text "active-user@arvados.local"
@@ -122,8 +122,7 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
 
   test "Inactive user can link to active account" do
     visit page_with_token('inactive_uninvited_trustedclient')
-    stub = start_sso_stub(api_fixture('api_client_authorizations')['active_trustedclient']['api_token'])
-    Rails.configuration.arvados_login_base = stub + "login"
+    Rails.configuration.testing_override_login_url = start_sso_stub(api_fixture('api_client_authorizations')['active_trustedclient']['api_token'])
 
     find("#notifications-menu").click
     assert_text "inactive-uninvited-user@arvados.local"
@@ -147,8 +146,7 @@ class LinkAccountTest < ActionDispatch::IntegrationTest
 
   test "Admin cannot link to non-admin" do
     visit page_with_token('admin_trustedclient')
-    stub = start_sso_stub(api_fixture('api_client_authorizations')['active_trustedclient']['api_token'])
-    Rails.configuration.arvados_login_base = stub + "login"
+    Rails.configuration.testing_override_login_url = start_sso_stub(api_fixture('api_client_authorizations')['active_trustedclient']['api_token'])
 
     find("#notifications-menu").click
     assert_text "admin@arvados.local"
index ac78344ea5b398566289c531f21400e3f5abc76b..279d851017f0a9270d970a39e5ce030659b30075 100644 (file)
@@ -93,7 +93,7 @@ class ProjectsTest < ActionDispatch::IntegrationTest
   end
 
   test "projects not publicly sharable when anonymous browsing disabled" do
-    Rails.configuration.anonymous_user_token = false
+    Rails.configuration.Users.AnonymousUserToken = ""
     open_groups_sharing
     # Check for a group we do expect first, to make sure the modal's loaded.
     assert_selector(".modal-container .selectable",
@@ -103,7 +103,7 @@ class ProjectsTest < ActionDispatch::IntegrationTest
   end
 
   test "projects publicly sharable when anonymous browsing enabled" do
-    Rails.configuration.anonymous_user_token = "testonlytoken"
+    Rails.configuration.Users.AnonymousUserToken = "testonlytoken"
     open_groups_sharing
     assert_selector(".modal-container .selectable",
                     text: group_name("anonymous_group"))
@@ -539,19 +539,19 @@ class ProjectsTest < ActionDispatch::IntegrationTest
   end
 
   test "error while loading tab" do
-    original_arvados_v1_base = Rails.configuration.arvados_v1_base
+    original_arvados_v1_base = Rails.configuration.Services.Controller.ExternalURL
 
     visit page_with_token 'active', '/projects/' + api_fixture('groups')['aproject']['uuid']
 
     # Point to a bad api server url to generate error
-    Rails.configuration.arvados_v1_base = "https://[::1]:1/"
+    Rails.configuration.Services.Controller.ExternalURL = "https://[::1]:1/"
     click_link 'Other objects'
     within '#Other_objects' do
       # Error
       assert_selector('a', text: 'Reload tab')
 
       # Now point back to the orig api server and reload tab
-      Rails.configuration.arvados_v1_base = original_arvados_v1_base
+      Rails.configuration.Services.Controller.ExternalURL = original_arvados_v1_base
       click_link 'Reload tab'
       assert_no_selector('a', text: 'Reload tab')
       assert_selector('button', text: 'Selection')
index dc898689e593b6992707ee6bcbb141f9e3329d5c..d2c4372bce0de489954afa620fabd861f1b42948 100644 (file)
@@ -7,11 +7,11 @@ require 'integration_helper'
 class ReportIssueTest < ActionDispatch::IntegrationTest
   setup do
     need_javascript
-    @user_profile_form_fields = Rails.configuration.user_profile_form_fields
+    @user_profile_form_fields = Rails.configuration.Workbench.UserProfileFormFields
   end
 
   teardown do
-    Rails.configuration.user_profile_form_fields = @user_profile_form_fields
+    Rails.configuration.Workbench.UserProfileFormFields = @user_profile_form_fields
   end
 
   # test version info and report issue from help menu
index e4d9894e5fb4e902f90dffc4019e2a771722cd37..547ef06a6827f013b0e958226e10d87ef57464fe 100644 (file)
@@ -7,20 +7,20 @@ require 'integration_helper'
 class UserProfileTest < ActionDispatch::IntegrationTest
   setup do
     need_javascript
-    @user_profile_form_fields = Rails.configuration.user_profile_form_fields
+    @user_profile_form_fields = Rails.configuration.Workbench.UserProfileFormFields
   end
 
   teardown do
-    Rails.configuration.user_profile_form_fields = @user_profile_form_fields
+    Rails.configuration.Workbench.UserProfileFormFields = @user_profile_form_fields
   end
 
   def verify_homepage_with_profile user, invited, has_profile
-    profile_config = Rails.configuration.user_profile_form_fields
+    profile_config = Rails.configuration.Workbench.UserProfileFormFields
 
     if !user
       assert_text('Please log in')
     elsif user['is_active']
-      if profile_config && !has_profile
+      if !profile_config.empty? && !has_profile
         assert_text('Save profile')
         add_profile user
       else
@@ -62,7 +62,7 @@ class UserProfileTest < ActionDispatch::IntegrationTest
             assert_selector('a', text: 'Current token')
             assert_selector('a', text: 'SSH keys')
 
-            if profile_config
+            if !profile_config.empty?
               assert_selector('a', text: 'Manage profile')
             else
               assert_no_selector('a', text: 'Manage profile')
@@ -96,14 +96,14 @@ class UserProfileTest < ActionDispatch::IntegrationTest
     assert_text('Save profile')
 
     # This time fill in required field and then save. Expect to go to requested page after that.
-    profile_message = Rails.configuration.user_profile_form_message
+    profile_message = Rails.configuration.Workbench.UserProfileFormMessage
     required_field_title = ''
     required_field_key = ''
-    profile_config = Rails.configuration.user_profile_form_fields
-    profile_config.each do |entry|
-      if entry['required']
-        required_field_key = entry['key']
-        required_field_title = entry['form_field_title']
+    profile_config = Rails.configuration.Workbench.UserProfileFormFields
+    profile_config.each do |k, entry|
+      if entry['Required']
+        required_field_key = k.to_s
+        required_field_title = entry['FormFieldTitle']
         break
       end
     end
@@ -142,11 +142,11 @@ class UserProfileTest < ActionDispatch::IntegrationTest
     [true, false].each do |profile_required|
       test "visit #{token} home page when profile is #{'not ' if !profile_required}configured" do
         if !profile_required
-          Rails.configuration.user_profile_form_fields = false
+          Rails.configuration.Workbench.UserProfileFormFields = []
         else
           # Our test config enabled profile by default. So, no need to update config
         end
-        Rails.configuration.enable_getting_started_popup = true
+        Rails.configuration.Workbench.EnableGettingStartedPopup = true
 
         if !token
           visit ('/')
index 6a0e46e26aea5b6455fd400ac73d55596ab5895b..562dc7d1f41cb885aee778aace35ae81d9e2d11f 100644 (file)
@@ -78,7 +78,7 @@ class UserSettingsMenuTest < ActionDispatch::IntegrationTest
 
   test "pipeline notification shown even though public pipelines exist" do
     skip "created_by doesn't work that way"
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
     visit page_with_token 'job_reader'
     click_link 'notifications-menu'
     assert_selector 'a', text: 'Click here to learn how to run an Arvados Crunch pipeline'
@@ -89,7 +89,7 @@ class UserSettingsMenuTest < ActionDispatch::IntegrationTest
     ['active'],
   ].each do |user, *expect|
     test "user settings menu for #{user} with notifications #{expect.inspect}" do
-      Rails.configuration.anonymous_user_token = false
+      Rails.configuration.Users.AnonymousUserToken = ""
       visit page_with_token(user)
       click_link 'notifications-menu'
       if expect.include? :ssh
index e377da3237ea69b820ece1125ee58d11cda4d4c4..a79220a8870095cb70315f088dab5ca7bb5c4743 100644 (file)
@@ -215,7 +215,7 @@ class WebsocketTest < ActionDispatch::IntegrationTest
     visit page_with_token("active", "/jobs/#{job['uuid']}\#Log")
 
     # Expect "all" historic log records because we have less than
-    # default Rails.configuration.running_job_log_records_to_fetch count
+    # default Rails.configuration.Workbench.RunningJobLogRecordsToFetch
     assert_text 'Historic log message'
 
     # Create new log record and expect it to show up in log tab
@@ -228,7 +228,7 @@ class WebsocketTest < ActionDispatch::IntegrationTest
 
   test "test running job with too many previous log records" do
     max = 5
-    Rails.configuration.running_job_log_records_to_fetch = max
+    Rails.configuration.Workbench.RunningJobLogRecordsToFetch = max
     job = api_fixture("jobs")['running']
 
     # Create max+1 log records
index e5cc6e4dc050d47bfa2d6220a4ec02528ef7aa05..b58d59a82ae414012935543d21bf9ec211274f01 100644 (file)
@@ -258,7 +258,7 @@ class WorkUnitsTest < ActionDispatch::IntegrationTest
       if token
         visit page_with_token token, "/#{type}/#{obj['uuid']}"
       else
-        Rails.configuration.anonymous_user_token =
+        Rails.configuration.Users.AnonymousUserToken =
           api_fixture("api_client_authorizations", "anonymous", "api_token")
         visit "/#{type}/#{obj['uuid']}"
       end
index 9337daf4eed8c1d90d31cb9537af8f5f50a4ff0c..34ee1f479a6a2a9a9eacd8402d79dd343bbaf08a 100644 (file)
@@ -164,8 +164,8 @@ module KeepWebConfig
   def use_keep_web_config
     @kwport = getport 'keep-web-ssl'
     @kwdport = getport 'keep-web-dl-ssl'
-    Rails.configuration.keep_web_url = "https://localhost:#{@kwport}/c=%{uuid_or_pdh}"
-    Rails.configuration.keep_web_download_url = "https://localhost:#{@kwdport}/c=%{uuid_or_pdh}"
+    Rails.configuration.Services.WebDAV.ExternalURL = URI("https://localhost:#{@kwport}")
+    Rails.configuration.Services.WebDAVDownload.ExternalURL = URI("https://localhost:#{@kwdport}")
   end
 end
 
index 44b9ad9e3e93d483c27cfb97aff5ad10b8b585b4..3feef945d1d6105301cf7fe4da32ba2ef2371115 100644 (file)
@@ -24,7 +24,7 @@ class BigCollectionTest < ActiveSupport::TestCase
   # didn't make a significant difference.
   [true].each do |compress|
     test "crud cycle for collection with big manifest (compress=#{compress})" do
-      Rails.configuration.api_response_compression = compress
+      Rails.configuration.Workbench.APIResponseCompression = compress
       Thread.current[:arvados_api_client] = nil
       crudtest
     end
index a71d0b46141fd74f2497e01447506831830d83d6..1d26deefa38bbe7c593d07d47dfe0d7d409cf49d 100644 (file)
@@ -61,11 +61,11 @@ class ActiveSupport::TestCase
   end
 
   def self.reset_application_config
-    $application_config.each do |k,v|
-      if k.match /^[^.]*$/
-        Rails.configuration.send (k + '='), v
-      end
-    end
+    # Restore configuration settings changed during tests
+    ConfigLoader.copy_into_config $arvados_config, Rails.configuration
+    ConfigLoader.copy_into_config $remaining_config, Rails.configuration
+    Rails.configuration.Services.Controller.ExternalURL = URI("https://#{ENV['ARVADOS_API_HOST']}")
+    Rails.configuration.TLS.Insecure = true
   end
 end
 
@@ -207,9 +207,6 @@ class ApiServerForTests
     end
 
     run_test_server
-    $application_config['arvados_login_base'] = "https://#{ENV['ARVADOS_API_HOST']}/login"
-    $application_config['arvados_v1_base'] = "https://#{ENV['ARVADOS_API_HOST']}/arvados/v1"
-    $application_config['arvados_insecure_host'] = true
     ActiveSupport::TestCase.reset_application_config
 
     @@server_is_running = true
index fa9a69d38097041b05c988eef8691a79d2182df3..a73e506d14ae6f7a4983da03be5e4105920cca5e 100644 (file)
@@ -16,7 +16,7 @@ class UserTest < ActiveSupport::TestCase
 
   test "User.current doesn't return anonymous user when using invalid token" do
     # Set up anonymous user token
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
     # First, try with a valid user
     use_token :active
     u = User.current
index eaf65c578dbfb3afbfbdbe3d39081ee25cdee778..4e5ad396789eb57c582101ba868a88e1a854d4d8 100644 (file)
@@ -9,7 +9,7 @@ class WorkUnitTest < ActiveSupport::TestCase
   reset_api_fixtures :after_each_test, false
 
   setup do
-    Rails.configuration.anonymous_user_token = api_fixture('api_client_authorizations')['anonymous']['api_token']
+    Rails.configuration.Users.AnonymousUserToken = api_fixture('api_client_authorizations')['anonymous']['api_token']
   end
 
   [
index 523205021304cb1462c4da66d966072293972e4a..0406b0ae03971c660e1764a759c435af972c5e48 100644 (file)
@@ -28,7 +28,7 @@ ubuntu1804/generated: common-generated-all
        test -d ubuntu1804/generated || mkdir ubuntu1804/generated
        cp -rlt ubuntu1804/generated common-generated/*
 
-GOTARBALL=go1.10.1.linux-amd64.tar.gz
+GOTARBALL=go1.12.7.linux-amd64.tar.gz
 NODETARBALL=node-v6.11.2-linux-x64.tar.xz
 RVMKEY1=mpapis.asc
 RVMKEY2=pkuczynski.asc
@@ -36,7 +36,7 @@ RVMKEY2=pkuczynski.asc
 common-generated-all: common-generated/$(GOTARBALL) common-generated/$(NODETARBALL) common-generated/$(RVMKEY1) common-generated/$(RVMKEY2)
 
 common-generated/$(GOTARBALL): common-generated
-       wget -cqO common-generated/$(GOTARBALL) http://storage.googleapis.com/golang/$(GOTARBALL)
+       wget -cqO common-generated/$(GOTARBALL) https://dl.google.com/go/$(GOTARBALL)
 
 common-generated/$(NODETARBALL): common-generated
        wget -cqO common-generated/$(NODETARBALL) https://nodejs.org/dist/v6.11.2/$(NODETARBALL)
index cc8265c3d4b3098aeff6ee46bfdeeb249cd823bc..610dac90fe89443ffe9a18f53d59b686429c7e3b 100644 (file)
@@ -19,7 +19,7 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
-ADD generated/go1.10.1.linux-amd64.tar.gz /usr/local/
+ADD generated/go1.12.7.linux-amd64.tar.gz /usr/local/
 RUN ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Install nodejs and npm
@@ -35,7 +35,11 @@ RUN scl enable rh-python35 "easy_install-3.5 pip" && easy_install-2.7 pip
 RUN wget http://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
 RUN rpm -ivh epel-release-latest-7.noarch.rpm
 
-RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
+RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle
+
+# Workbench depends on arvados-server for config manipulation
+ENV GOPATH /tmp
+RUN mkdir -p $GOPATH/src/git.curoverse.com && ln -sT /tmp/arvados $GOPATH/src/git.curoverse.com/arvados.git && cd $GOPATH/src/git.curoverse.com/arvados.git/cmd/arvados-server && go get -v github.com/kardianos/govendor && $GOPATH/bin/govendor sync && go get && go build && cp arvados-server /usr/local/bin/ && rm -rf /tmp/arvados
 
 # The version of setuptools that comes with CentOS is way too old
 RUN pip install --upgrade setuptools
index a1a1ed6f798676be5e862551df47952d80eb0e1e..4dc78de00a1998b4689961f50d7887c96cf58449 100644 (file)
@@ -26,14 +26,18 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
-ADD generated/go1.10.1.linux-amd64.tar.gz /usr/local/
+ADD generated/go1.12.7.linux-amd64.tar.gz /usr/local/
 RUN ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Install nodejs and npm
 ADD generated/node-v6.11.2-linux-x64.tar.xz /usr/local/
 RUN ln -s /usr/local/node-v6.11.2-linux-x64/bin/* /usr/local/bin/
 
-RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
+RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle
+
+# Workbench depends on arvados-server for config manipulation
+ENV GOPATH /tmp
+RUN mkdir -p $GOPATH/src/git.curoverse.com && ln -sT /tmp/arvados $GOPATH/src/git.curoverse.com/arvados.git && cd $GOPATH/src/git.curoverse.com/arvados.git/cmd/arvados-server && go get -v github.com/kardianos/govendor && $GOPATH/bin/govendor sync && go get && go build && cp arvados-server /usr/local/bin/ && rm -rf /tmp/arvados
 
 ENV WORKSPACE /arvados
 CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "debian8"]
index 770db51e7c5180bd0ba83d7e5c57d2899b269c61..f8104472b6dd20e81988c3505646af5ae0f629df 100644 (file)
@@ -25,14 +25,18 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
-ADD generated/go1.10.1.linux-amd64.tar.gz /usr/local/
+ADD generated/go1.12.7.linux-amd64.tar.gz /usr/local/
 RUN ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Install nodejs and npm
 ADD generated/node-v6.11.2-linux-x64.tar.xz /usr/local/
 RUN ln -s /usr/local/node-v6.11.2-linux-x64/bin/* /usr/local/bin/
 
-RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
+RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle
+
+# Workbench depends on arvados-server for config manipulation
+ENV GOPATH /tmp
+RUN mkdir -p $GOPATH/src/git.curoverse.com && ln -sT /tmp/arvados $GOPATH/src/git.curoverse.com/arvados.git && cd $GOPATH/src/git.curoverse.com/arvados.git/cmd/arvados-server && go get -v github.com/kardianos/govendor && $GOPATH/bin/govendor sync && go get && go build && cp arvados-server /usr/local/bin/ && rm -rf /tmp/arvados
 
 ENV WORKSPACE /arvados
 CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "debian9"]
index 4c01c9e8180fefb268ff80e9d930f339144eb879..a356b1c798dec7ec7c2c496b20d7dc51da4e8042 100644 (file)
@@ -25,14 +25,18 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
-ADD generated/go1.10.1.linux-amd64.tar.gz /usr/local/
+ADD generated/go1.12.7.linux-amd64.tar.gz /usr/local/
 RUN ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Install nodejs and npm
 ADD generated/node-v6.11.2-linux-x64.tar.xz /usr/local/
 RUN ln -s /usr/local/node-v6.11.2-linux-x64/bin/* /usr/local/bin/
 
-RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
+RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle
+
+# Workbench depends on arvados-server for config manipulation
+ENV GOPATH /tmp
+RUN mkdir -p $GOPATH/src/git.curoverse.com && ln -sT /tmp/arvados $GOPATH/src/git.curoverse.com/arvados.git && cd $GOPATH/src/git.curoverse.com/arvados.git/cmd/arvados-server && go get -v github.com/kardianos/govendor && $GOPATH/bin/govendor sync && go get && go build && cp arvados-server /usr/local/bin/ && rm -rf /tmp/arvados
 
 ENV WORKSPACE /arvados
 CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu1404"]
index dac82097bd6c7b3ab4b9dd02a5e41dbb88f6fc61..63c119c8405f1dc38020db111656af3d12576310 100644 (file)
@@ -24,14 +24,18 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
-ADD generated/go1.10.1.linux-amd64.tar.gz /usr/local/
+ADD generated/go1.12.7.linux-amd64.tar.gz /usr/local/
 RUN ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Install nodejs and npm
 ADD generated/node-v6.11.2-linux-x64.tar.xz /usr/local/
 RUN ln -s /usr/local/node-v6.11.2-linux-x64/bin/* /usr/local/bin/
 
-RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
+RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle
+
+# Workbench depends on arvados-server for config manipulation
+ENV GOPATH /tmp
+RUN mkdir -p $GOPATH/src/git.curoverse.com && ln -sT /tmp/arvados $GOPATH/src/git.curoverse.com/arvados.git && cd $GOPATH/src/git.curoverse.com/arvados.git/cmd/arvados-server && go get -v github.com/kardianos/govendor && $GOPATH/bin/govendor sync && go get && go build && cp arvados-server /usr/local/bin/ && rm -rf /tmp/arvados
 
 ENV WORKSPACE /arvados
 CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu1604"]
index fdfbd04206f4a90e923034dcaee1474504b3e149..5e4d067671777843373536fe7b2ad42b98cf00e0 100644 (file)
@@ -24,14 +24,18 @@ RUN gpg --import --no-tty /tmp/mpapis.asc && \
     /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.10.2
 
 # Install golang binary
-ADD generated/go1.10.1.linux-amd64.tar.gz /usr/local/
+ADD generated/go1.12.7.linux-amd64.tar.gz /usr/local/
 RUN ln -s /usr/local/go/bin/go /usr/local/bin/
 
 # Install nodejs and npm
 ADD generated/node-v6.11.2-linux-x64.tar.xz /usr/local/
 RUN ln -s /usr/local/node-v6.11.2-linux-x64/bin/* /usr/local/bin/
 
-RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle && rm -rf /tmp/arvados
+RUN git clone --depth 1 git://git.curoverse.com/arvados.git /tmp/arvados && cd /tmp/arvados/services/api && /usr/local/rvm/bin/rvm-exec default bundle && cd /tmp/arvados/apps/workbench && /usr/local/rvm/bin/rvm-exec default bundle
+
+# Workbench depends on arvados-server for config manipulation
+ENV GOPATH /tmp
+RUN mkdir -p $GOPATH/src/git.curoverse.com && ln -sT /tmp/arvados $GOPATH/src/git.curoverse.com/arvados.git && cd $GOPATH/src/git.curoverse.com/arvados.git/cmd/arvados-server && go get -v github.com/kardianos/govendor && $GOPATH/bin/govendor sync && go get && go build && cp arvados-server /usr/local/bin/ && rm -rf /tmp/arvados
 
 ENV WORKSPACE /arvados
 CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu1804"]
index 789a7ee17e6cd6dd514e10ac1e7ea40840d76102..56d55d3276472c43d0fcbd268fefe76b7fb7e6de 100644 (file)
@@ -259,4 +259,8 @@ elif [ "$1" = "0" ] || [ "$1" = "1" ] || [ "$1" = "2" ]; then
 fi
 
 report_not_ready "$DATABASE_READY" "$CONFIG_PATH/database.yml"
-report_not_ready "$APPLICATION_READY" "$CONFIG_PATH/application.yml"
+if printf '%s\n' "$CONFIG_PATH" | grep -Fqe "sso"; then
+       report_not_ready "$APPLICATION_READY" "$CONFIG_PATH/application.yml"
+else
+       report_not_ready "$APPLICATION_READY" "/etc/arvados/config.yml"
+fi
index bd55fb9518cf2e3b31f2c6c07472d9c06fd7d45f..8a675492e770524ab9debd8b8dd7904e4110b679 100755 (executable)
@@ -384,17 +384,17 @@ if [[ "$?" == "0" ]] ; then
       rm -rf tmp
       mkdir tmp
 
-      # Set up application.yml and production.rb so that asset precompilation works
-      \cp config/application.yml.example config/application.yml -f
-      \cp config/environments/production.rb.example config/environments/production.rb -f
-      sed -i 's/secret_token: ~/secret_token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/' config/application.yml
-      sed -i 's/keep_web_url: false/keep_web_url: exampledotcom/' config/application.yml
+      # Set up an appropriate config.yml
+      arvados-server config-dump -config <(cat /etc/arvados/config.yml 2>/dev/null || echo  "Clusters: {zzzzz: {}}") > /tmp/x
+      mkdir -p /etc/arvados/
+      mv /tmp/x /etc/arvados/config.yml
+      perl -p -i -e 'BEGIN{undef $/;} s/WebDAV(.*?):\n( *)ExternalURL: ""/WebDAV$1:\n$2ExternalURL: "example.com"/g' /etc/arvados/config.yml
 
       RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake npm:install >/dev/null
       RAILS_ENV=production RAILS_GROUPS=assets bundle exec rake assets:precompile >/dev/null
 
       # Remove generated configuration files so they don't go in the package.
-      rm config/application.yml config/environments/production.rb
+      rm -rf /etc/arvados/
   )
 
   if [[ "$?" != "0" ]]; then
index b0068d2112a9ee14d422bb3320126063456f50f8..ea81bbf17c4785dd6bd6c0d26f27b6ea66556004 100755 (executable)
@@ -352,15 +352,6 @@ handle_rails_package() {
     if  [[ "$pkgname" != "arvados-workbench" ]]; then
       exclude_list+=('config/database.yml')
     fi
-    # for arvados-api-server, we need to dereference the
-    # config/config.default.yml file. There is no fpm way to do that, sadly
-    # (excluding the existing symlink and then adding the file from its source
-    # path doesn't work, sadly.
-    if [[ "$pkgname" == "arvados-api-server" ]]; then
-      mv /arvados/services/api/config/config.default.yml /arvados/services/api/config/config.default.yml.bu
-      cp -p /arvados/lib/config/config.default.yml /arvados/services/api/config/
-      exclude_list+=('config/config.default.yml.bu')
-    fi
     for exclude in ${exclude_list[@]}; do
         switches+=(-x "$exclude_root/$exclude")
     done
@@ -368,11 +359,6 @@ handle_rails_package() {
               -x "$exclude_root/vendor/cache-*" \
               -x "$exclude_root/vendor/bundle" "$@" "$license_arg"
     rm -rf "$scripts_dir"
-    # Undo the deferencing we did above
-    if [[ "$pkgname" == "arvados-api-server" ]]; then
-      rm -f /arvados/services/api/config/config.default.yml
-      mv /arvados/services/api/config/config.default.yml.bu /arvados/services/api/config/config.default.yml
-    fi
 }
 
 # Build python packages with a virtualenv built-in
index 51d80c34ae889dee44b2ba3660fdd55984935b61..7c21a296406d42c7f06fbc88fcfcae0dd2509ad8 100755 (executable)
@@ -209,8 +209,8 @@ sanity_checks() {
     echo -n 'go: '
     go version \
         || fatal "No go binary. See http://golang.org/doc/install"
-    [[ $(go version) =~ go1.([0-9]+) ]] && [[ ${BASH_REMATCH[1]} -ge 10 ]] \
-        || fatal "Go >= 1.10 required. See http://golang.org/doc/install"
+    [[ $(go version) =~ go1.([0-9]+) ]] && [[ ${BASH_REMATCH[1]} -ge 12 ]] \
+        || fatal "Go >= 1.12 required. See http://golang.org/doc/install"
     echo -n 'gcc: '
     gcc --version | egrep ^gcc \
         || fatal "No gcc. Try: apt-get install build-essential"
@@ -616,6 +616,8 @@ initialize() {
     export R_LIBS
 
     export GOPATH
+    # Make sure our compiled binaries under test override anything
+    # else that might be in the environment.
     export PATH=$GOPATH/bin:$PATH
 
     # Jenkins config requires that glob tmp/*.log match something. Ensure
@@ -990,7 +992,7 @@ pythonstuff=(
 )
 
 declare -a gostuff
-gostuff=($(git grep -lw func | grep \\.go | sed -e 's/\/[^\/]*$//' | sort -u))
+gostuff=($(cd "$WORKSPACE" && git grep -lw func | grep \\.go | sed -e 's/\/[^\/]*$//' | sort -u))
 
 install_apps/workbench() {
     cd "$WORKSPACE/apps/workbench" \
@@ -1157,11 +1159,11 @@ install_all() {
             fi
         fi
     done
-    do_install services/api
     for g in "${gostuff[@]}"
     do
         do_install "$g" go
     done
+    do_install services/api
     do_install apps/workbench
 }
 
@@ -1238,6 +1240,13 @@ for p in "${pythonstuff[@]}"; do
 done
 
 testfuncargs["sdk/cli"]="sdk/cli"
+testfuncargs["sdk/R"]="sdk/R"
+testfuncargs["sdk/java-v2"]="sdk/java-v2"
+testfuncargs["apps/workbench_units"]="apps/workbench_units"
+testfuncargs["apps/workbench_functionals"]="apps/workbench_functionals"
+testfuncargs["apps/workbench_integration"]="apps/workbench_integration"
+testfuncargs["apps/workbench_benchmark"]="apps/workbench_benchmark"
+testfuncargs["apps/workbench_profile"]="apps/workbench_profile"
 
 if [[ -z ${interactive} ]]; then
     install_all
index 2506bd2c98892579c974c93f925673277c4c3172..dd34eff7d44855826cdaaf13efa59b6091a79060 100644 (file)
@@ -21,11 +21,12 @@ var (
                "-version":  cmd.Version(version),
                "--version": cmd.Version(version),
 
-               "cloudtest":      cloudtest.Command,
-               "config-check":   config.CheckCommand,
-               "config-dump":    config.DumpCommand,
-               "controller":     controller.Command,
-               "dispatch-cloud": dispatchcloud.Command,
+               "cloudtest":       cloudtest.Command,
+               "config-check":    config.CheckCommand,
+               "config-dump":     config.DumpCommand,
+               "config-defaults": config.DumpDefaultsCommand,
+               "controller":      controller.Command,
+               "dispatch-cloud":  dispatchcloud.Command,
        })
 )
 
index a65aec9b945b3cbe58cb4fea5985c02eb959bbb9..7e0cb0d518e1e7ad6506500fb577f3d146c24fc1 100644 (file)
@@ -10,6 +10,6 @@ import arvados.util as util
 filters = [['properties.responsible_person_uuid', 'exists', False]]
 cols = util.list_all(arvados.api().collections().list, filters=filters, select=['uuid', 'name'])
 
-print("Found {} collections:".format(len(cols)))
+print('Found {} collections:'.format(len(cols)))
 for c in cols:
     print('{}, "{}"'.format(c['uuid'], c['name']))
\ No newline at end of file
index 06ef6f097ad051359e1084039cf62cf973bfe03b..073db7ac690dff82c1438da3a8ceb3b9089a66d6 100644 (file)
@@ -28,9 +28,9 @@ for p_uuid in [root_uuid] + get_subproject_uuids(api, root_uuid):
     f = [['properties.responsible_person_uuid', 'exists', False],
          ['owner_uuid', '=', p_uuid]]
     cols = get_cols(api, f)
-    print("Found {} collections owned by {}".format(len(cols), p_uuid))
+    print('Found {} collections owned by {}'.format(len(cols), p_uuid))
     for c in cols:
-        print(" - Updating collection {}".format(c["uuid"]))
+        print(' - Updating collection {}'.format(c['uuid']))
         props = c['properties']
         props['responsible_person_uuid'] = responsible_uuid
         api.collections().update(uuid=c['uuid'], body={'properties': props}).execute()
\ No newline at end of file
index a2a8f9d82ae70d0bfbe0e40c06e777f0d79f16b8..d84e34699bf3f3f3ceaaca8667e31c8952cee6cb 100644 (file)
@@ -7,16 +7,16 @@ SPDX-License-Identifier: CC-BY-SA-3.0
 import arvados
 import arvados.util as util
 
-old_uuid = "zzzzz-tpzed-xxxxxxxxxxxxxxx"
-new_uuid = "zzzzz-tpzed-yyyyyyyyyyyyyyy"
+old_uuid = 'zzzzz-tpzed-xxxxxxxxxxxxxxx'
+new_uuid = 'zzzzz-tpzed-yyyyyyyyyyyyyyy'
 
 api = arvados.api()
 filters = [['properties.responsible_person_uuid', '=', '{}'.format(old_uuid)]]
 cols = util.list_all(api.collections().list, filters=filters, select=['uuid', 'properties'])
 
-print("Found {} collections".format(len(cols)))
+print('Found {} collections'.format(len(cols)))
 for c in cols:
-    print("Updating collection {}".format(c["uuid"]))
+    print('Updating collection {}'.format(c['uuid']))
     props = c['properties']
     props['responsible_person_uuid'] = new_uuid
     api.collections().update(uuid=c['uuid'], body={'properties': props}).execute()
\ No newline at end of file
index 11546c032327385b680fe617885bbaac6055bbf8..4862bfe3334b02f57a439fa9e0e9e5ff6f63c679 100644 (file)
@@ -23,7 +23,28 @@ $ bundle exec rake config:migrate > config.yml
 $ cp config.yml /etc/arvados/config.yml
 </pre>
 
-This will print the contents of @config.yml@ after merging with legacy @application.yml@.  It may then be redirected to a file and copied to @/etc/arvados/config.yml@.
+This will print the contents of @config.yml@ after merging the legacy @application.yml@ and @database.yml@ into the existing systemwide @config.yml@.  It may be redirected to a file and copied to @/etc/arvados/config.yml@ (it is safe to copy over, all configuration items from the existing @/etc/arvados/config.yml@ will be included in the migrated output).
+
+If you wish to update @config.yml@ configuration by hand, or check that everything has been migrated, use @config:diff@ to print configuration items that differ between @application.yml@ and the system @config.yml@.
+
+<pre>
+$ bundle exec rake config:diff
+</pre>
+
+This command will also report if no migrations are required.
+
+h2. Workbench
+
+The legacy workbench configuration is stored in @config/application.yml@.  After migration to @/etc/arvados/config.yml@, this file should be moved out of the way and/or deleted.
+
+Change to the workbench server directory and use the following commands:
+
+<pre>
+$ bundle exec rake config:migrate > config.yml
+$ cp config.yml /etc/arvados/config.yml
+</pre>
+
+This will print the contents of @config.yml@ after merging the legacy @application.yml@ into the existing systemwide @config.yml@.  It may be redirected to a file and copied to @/etc/arvados/config.yml@ (it is safe to copy over, all configuration items from the existing @/etc/arvados/config.yml@ will be included in the migrated output).
 
 If you wish to update @config.yml@ configuration by hand, or check that everything has been migrated, use @config:diff@ to print configuration items that differ between @application.yml@ and the system @config.yml@.
 
@@ -43,8 +64,8 @@ Currently only reads @RemoteClusters@ from centralized configuration.  Still req
 
 h2. arvados-controller
 
-Only supports centralized config file.  No migration needed.
+Already uses centralized config exclusively.  No migration needed.
 
 h2. arvados-dispatch-cloud
 
-Only supports centralized config file.  No migration needed.
+Already uses centralized config exclusively.  No migration needed.
index 18e1abae3a9f1b81660c964b2be9a678decb667f..da37d743de4aa43d821ff449f7a21d772af73bb2 100644 (file)
@@ -76,6 +76,10 @@ The "postgres-contrib package":https://www.postgresql.org/docs/10/contrib.html h
 
 Subsequently, the <code class="userinput">psql -d 'arvados_production' -c '\dx'</code> command will display the installed extensions for the arvados_production database. This list should now contain @pg_trgm@.
 
+h4. Migrating to centralized config.yml
+
+See "Migrating Configuration":config-migration.html for notes on migrating legacy per-component configuration files to the new centralized @/etc/arvados/config.yml@.  To ensure a smooth transition, the per-component config files continue to be read, and take precedence over the centralized configuration.
+
 h3(#v1_4_0). v1.4.0 (2019-06-05)
 
 h4. Populating the new file_count and file_size_total columns on the collections table
index 4f97ba4cef5b5f6dd023aa97317840700ba82100..0e01b3c6dd740abe04210381bd0877931e1366c3 100644 (file)
@@ -107,9 +107,20 @@ table(table table-bordered table-condensed).
 |@is_a@|string|Arvados object type|@["head_uuid","is_a","arvados#collection"]@|
 |@exists@|string|Test if a subproperty is present.|@["properties","exists","my_subproperty"]@|
 
+
+h4(#substringsearchfilter). Filtering using substring search
+
+Resources can also be filtered by searching for a substring in attributes of type @string@, @array of strings@, @text@, and @hash@, which are indexed in the database specifically for search. To use substring search, the filter must:
+
+* Specify @any@ as the attribute
+* Use either the @like@ or @ilike@ operator
+* Have an operand of type @string@ that is wrapped in the SQL pattern match wildcard character @%@
+
+For example, the @["any", "like", "%foo%"]@ filter will return all resources that contain @foo@ in the content of at least one attribute of the previously defined types. This is the recommended way to do keyword and file name search across the entire database. Note that only exact substring matches are returned and results are unranked and returned in the order specified by the @list@ @order@ argument.
+
 h4(#subpropertyfilters). Filtering on subproperties
 
-Some record type have an additional @properties@ attribute that allows recording and filtering on additional key-value pairs.  To filter on a subproperty, the value in the @attribute@ position has the form @properties.user_property@.  You may also use JSON-LD / RDF style URIs for property keys by enclosing them in @<...>@ for example @properties.<http://example.com/user_property>@.  Alternately you may also provide a JSON-LD "@context" field, however at this time JSON-LD contexts are not interpreted by Arvados.
+Some record types have an additional @properties@ attribute that allows recording and filtering on additional key-value pairs.  To filter on a subproperty, the value in the @attribute@ position has the form @properties.user_property@.  You may also use JSON-LD / RDF style URIs for property keys by enclosing them in @<...>@ for example @properties.<http://example.com/user_property>@.  Alternately you may also provide a JSON-LD "@context" field, however at this time JSON-LD contexts are not interpreted by Arvados.
 
 table(table table-bordered table-condensed).
 |_. Operator|_. Operand type|_. Description|_. Example|
index c31b2ed43c89b92b5ef8c5c15c8abdd4dd185cbe..7181fed5cffac0a9491c5fd5870ff983be1cf09a 100644 (file)
@@ -9,7 +9,7 @@ Copyright (C) The Arvados Authors. All rights reserved.
 SPDX-License-Identifier: CC-BY-SA-3.0
 {% endcomment %}
 
-Arvados components run on GNU/Linux systems, and supports multiple cloud operating stacks.  Arvados supports Debian and derivatives such as Ubuntu, as well as Red Hat and derivatives such as CentOS.
+Arvados components run on GNU/Linux systems, and supports multiple cloud operating stacks.  Arvados supports Debian and derivatives such as Ubuntu, as well as Red Hat and derivatives such as CentOS.  Although Arvados development is sponsored by Veritas Genetics which offers commercial support, "Arvados is Free Software":{{site.baseurl}}/copying/copying.html and we encourage self supported/community supported installations.
 
 Arvados components can be installed and configured in a number of different ways.
 
index a6b843b160ba39161850005b0de858daab867ac4..424fc3cf242536bc95dbe34697f27c8166eb1b58 100644 (file)
@@ -35,102 +35,124 @@ On a Red Hat-based system, install the following packages:
 
 {% include 'install_git' %}
 
-h2(#configure). Set up the database
-
-Configure the API server to connect to your database by updating @/etc/arvados/api/database.yml@. Replace the @xxxxxxxx@ database password placeholder with the "password you generated during database setup":install-postgresql.html#api. Be sure to update the @production@ section.
-
-<notextile>
-<pre><code>~$ <span class="userinput">editor /etc/arvados/api/database.yml</span>
-</code></pre></notextile>
-
 h2(#configure_application). Configure the API server
 
-Edit @/etc/arvados/api/application.yml@ to configure the settings described in the following sections.  The API server reads both @application.yml@ and its own @config/application.default.yml@ file.  The settings in @application.yml@ take precedence over the defaults that are defined in @config/application.default.yml@.  The @config/application.yml.example@ file is not read by the API server and is provided as a starting template only.
+Edit @/etc/arvados/config.yml@ to set the keys below.  Only the most important configuration options are listed here.  The example configuration fragments given below should be merged into a single configuration structure.  Correct indentation is important.  The full set of configuration options are listed in "config.yml":{{site.baseurl}}/admin/config.html
 
-@config/application.default.yml@ documents additional configuration settings not listed here.  You can "view the current source version":https://dev.arvados.org/projects/arvados/repository/revisions/master/entry/services/api/config/application.default.yml for reference.
+h3(#uuid_prefix). ClusterID
 
-Only put local configuration in @application.yml@.  Do not edit @application.default.yml@.
+The @ClusterID@ is used for all database identifiers to identify the record as originating from this site.  It is the first key under @Clusters@ in @config.yml@.  It must be exactly 5 lowercase ASCII letters and digits.  All configuration items go under the cluster id key (replace @zzzzz@ with your cluster id in the examples below).
 
-h3(#uuid_prefix). uuid_prefix
+<notextile>
+<pre><code>Clusters:
+  <span class="userinput">zzzzz</span>:
+    ...</code></pre>
+</notextile>
 
-Define your @uuid_prefix@ in @application.yml@ by setting the @uuid_prefix@ field in the section for your environment.  This prefix is used for all database identifiers to identify the record as originating from this site.  It must be exactly 5 lowercase ASCII letters and digits.
+h3(#configure). PostgreSQL.Connection
 
-Example @application.yml@:
+Replace the @xxxxxxxx@ database password placeholder with the "password you generated during database setup":install-postgresql.html#api.
 
 <notextile>
-<pre><code>  uuid_prefix: <span class="userinput">zzzzz</span></code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    PostgreSQL:
+      Connection:
+        host: <span class="userinput">localhost</span>
+        user: <span class="userinput">arvados</span>
+        password: <span class="userinput">xxxxxxxx</span>
+        dbname: <span class="userinput">arvados_production</span>
+      </code></pre>
 </notextile>
 
-h3. secret_token
+h3. API.RailsSessionSecretToken
 
-The @secret_token@ is used for for signing cookies.  IMPORTANT: This is a site secret. It should be at least 50 characters.  Generate a random value and set it in @application.yml@:
+The @API.RailsSessionSecretToken@ is used for for signing cookies.  IMPORTANT: This is a site secret. It should be at least 50 characters.  Generate a random value and set it in @config.yml@:
 
 <notextile>
 <pre><code>~$ <span class="userinput">ruby -e 'puts rand(2**400).to_s(36)'</span>
 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
 </code></pre></notextile>
 
-Example @application.yml@:
+Example @config.yml@:
 
 <notextile>
-<pre><code>  secret_token: <span class="userinput">yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy</span></code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    API:
+      RailsSessionSecretToken: <span class="userinput">yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy</span></code></pre>
 </notextile>
 
-h3(#blob_signing_key). blob_signing_key
+h3(#blob_signing_key). Collections.BlobSigningKey
 
-The @blob_signing_key@ is used to enforce access control to Keep blocks.  This same key must be provided to the Keepstore daemons when "installing Keepstore servers.":install-keepstore.html  IMPORTANT: This is a site secret. It should be at least 50 characters.  Generate a random value and set it in @application.yml@:
+The @Collections.BlobSigningKey@ is used to enforce access control to Keep blocks.  This same key must be provided to the Keepstore daemons when "installing Keepstore servers.":install-keepstore.html  IMPORTANT: This is a site secret. It should be at least 50 characters.  Generate a random value and set it in @config.yml@:
 
 <notextile>
 <pre><code>~$ <span class="userinput">ruby -e 'puts rand(2**400).to_s(36)'</span>
 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 </code></pre></notextile>
 
-Example @application.yml@:
+Example @config.yml@:
 
 <notextile>
-<pre><code>  blob_signing_key: <span class="userinput">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span></code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Collections:
+      BlobSigningKey: <span class="userinput">xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span></code></pre>
 </notextile>
 
-h3(#omniauth). sso_app_secret, sso_app_id, sso_provider_url
+h3(#omniauth). Login.ProviderAppID, Login.ProviderAppSecret, Services.SSO.ExternalURL
 
 The following settings enable the API server to communicate with the "Single Sign On (SSO) server":install-sso.html to authenticate user log in.
 
-Set @sso_provider_url@ to the base URL where your SSO server is installed.  This should be a URL consisting of the scheme and host (and optionally, port), without a trailing slash.
+Set @Services.SSO.ExternalURL@ to the base URL where your SSO server is installed.  This should be a URL consisting of the scheme and host (and optionally, port), without a trailing slash.
 
-Set @sso_app_secret@ and @sso_app_id@ to the corresponding values for @app_secret@ and @app_id@ used in the "Create arvados-server client for Single Sign On (SSO)":install-sso.html#client step.
+Set @Login.ProviderAppID@ and @Login.ProviderAppSecret@ to the corresponding values for @app_id@ and @app_secret@ used in the "Create arvados-server client for Single Sign On (SSO)":install-sso.html#client step.
 
-Example @application.yml@:
+Example @config.yml@:
 
 <notextile>
-<pre><code>  sso_app_id: <span class="userinput">arvados-server</span>
-  sso_app_secret: <span class="userinput">wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww</span>
-  sso_provider_url: <span class="userinput">https://sso.example.com</span>
-</code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Services:
+      SSO:
+        ExternalURL: <span class="userinput">https://sso.example.com</span>
+    Login:
+      ProviderAppID: <span class="userinput">arvados-server</span>
+      ProviderAppSecret: <span class="userinput">wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww</span></code></pre>
 </notextile>
 
-h3. workbench_address
+h3. Services.Workbench1.ExternalURL
 
-Set @workbench_address@ to the URL of your workbench application after following "Install Workbench.":install-workbench-app.html
+Set @Services.Workbench1.ExternalURL@ to the URL of your workbench application after following "Install Workbench.":install-workbench-app.html
 
-Example @application.yml@:
+Example @config.yml@:
 
 <notextile>
-<pre><code>  workbench_address: <span class="userinput">https://workbench.zzzzz.example.com</span></code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Services:
+      Workbench1:
+        ExternalURL: <span class="userinput">https://workbench.zzzzz.example.com</span></code></pre>
 </notextile>
 
-h3. websocket_address
+h3. Services.Websocket.ExternalURL
 
-Set @websocket_address@ to the @wss://@ URL of the API server websocket endpoint after following "Set up Web servers":#set_up.  The path of the default endpoint is @/websocket@.
+Set @Services.Websocket.ExternalURL@ to the @wss://@ URL of the API server websocket endpoint after following "Install the websocket server":install-ws.html .
 
-Example @application.yml@:
+Example @config.yml@:
 
 <notextile>
-<pre><code>  websocket_address: <span class="userinput">wss://ws.zzzzz.example.com</span>/websocket</code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Services:
+      Websocket:
+        ExternalURL: <span class="userinput">wss://ws.zzzzz.example.com</span></code></pre>
 </notextile>
 
-h3(#git_repositories_dir). git_repositories_dir
+h3(#git_repositories_dir). Git.Repositories
 
-The @git_repositories_dir@ setting specifies the directory where user git repositories will be stored.
+The @Git.Repositories@ setting specifies the directory where user git repositories will be stored.
 
 The git server setup process is covered on "its own page":install-arv-git-httpd.html. For now, create an empty directory in the default location:
 
@@ -138,39 +160,47 @@ The git server setup process is covered on "its own page":install-arv-git-httpd.
 <pre><code>~$ <span class="userinput">sudo mkdir -p /var/lib/arvados/git/repositories</span>
 </code></pre></notextile>
 
-If you intend to store your git repositories in a different location, specify that location in @application.yml@.
-
-Default setting in @application.default.yml@:
+If you intend to store your git repositories in a different location, specify that location in @config.yml@.  Example:
 
 <notextile>
-<pre><code>  git_repositories_dir: <span class="userinput">/var/lib/arvados/git/repositories</span>
-</code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Git:
+      Repositories: <span class="userinput">/var/lib/arvados/git/repositories</span></code></pre>
 </notextile>
 
-h3(#git_internal_dir). git_internal_dir
+h3(#enable_legacy_jobs_api). Containers.JobsAPI.Enable
+
+Enable the legacy "Jobs API":install-crunch-dispatch.html .  Note: new installations should use the "Containers API":crunch2-slurm/install-prerequisites.html
 
-The @git_internal_dir@ setting specifies the location of Arvados' internal git repository.  By default this is @/var/lib/arvados/internal.git@.  This repository stores git commits that have been used to run Crunch jobs.  It should _not_ be a subdirectory of @git_repositories_dir@.
+Disabling the jobs API means methods involving @jobs@, @job_tasks@, @pipeline_templates@ and @pipeline_instances@ are disabled.  This functionality is superceded by the containers API which consists of @container_requests@, @containers@ and @workflows@.  Arvados clients (such as @arvados-cwl-runner@) detect which APIs are available and adjust behavior accordingly.  Note the configuration value must be a quoted string.
 
-Example @application.yml@:
+* 'auto' -- (default) enable the Jobs API only if it has been used before (i.e., there are job records in the database), otherwise disable jobs API .
+* 'true' -- enable the Jobs API even if there are no existing job records.
+* 'false' -- disable the Jobs API even in the presence of existing job records.
 
 <notextile>
-<pre><code>  git_internal_dir: <span class="userinput">/var/lib/arvados/internal.git</span>
-</code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Containers:
+      JobsAPI:
+        Enable: <span class="userinput">'auto'</span></code></pre>
 </notextile>
 
-h3(#enable_legacy_jobs_api). enable_legacy_jobs_api
+h4(#git_internal_dir). Containers.JobsAPI.GitInternalDir
 
-Enable the legacy "Jobs API":install-crunch-dispatch.html .  Note: new installations should use the "Containers API":crunch2-slurm/install-prerequisites.html
+Only required if the legacy "Jobs API" is enabled, otherwise you should skip this.
 
-Disabling the jobs API means methods involving @jobs@, @job_tasks@, @pipeline_templates@ and @pipeline_instances@ are disabled.  This functionality is superceded by the containers API which consists of @container_requests@, @containers@ and @workflows@.  Arvados clients (such as @arvados-cwl-runner@) detect which APIs are available and adjust behavior accordingly.
+The @Containers.JobsAPI.GitInternalDir@ setting specifies the location of Arvados' internal git repository.  By default this is @/var/lib/arvados/internal.git@.  This repository stores git commits that have been used to run Crunch jobs.  It should _not_ be a subdirectory of the directory in @Git.Repositories@.
 
-* auto -- (default) enable the Jobs API only if it has been used before (i.e., there are job records in the database), otherwise disable jobs API .
-* true -- enable the Jobs API even if there are no existing job records.
-* false -- disable the Jobs API even in the presence of existing job records.
+Example @config.yml@:
 
 <notextile>
-<pre><code>  enable_legacy_jobs_api: <span class="userinput">auto</span>
-</code></pre>
+<pre><code>Clusters:
+  zzzzz:
+    Containers:
+      JobsAPI:
+        GitInternalDir: <span class="userinput">/var/lib/arvados/internal.git</span></code></pre>
 </notextile>
 
 h2(#set_up). Set up Nginx and Passenger
@@ -199,7 +229,7 @@ server {
   # also ensure the following settings match it:
   # * `client_max_body_size` in the server section below
   # * `client_max_body_size` in the Workbench Nginx configuration (twice)
-  # * `max_request_size` in the API server's application.yml file
+  # * `API.MaxRequestSize` in config.yml
   client_max_body_size 128m;
 }
 
index d72909077e97f4fca2c2c43cf748f7ede66dd723..5d497cc114cd52ff1caa161181ee68ab1d7badf3 100644 (file)
@@ -59,7 +59,7 @@ You can delete the key files after you have copied the private key to your confi
 
 h2. Configure the dispatcher
 
-Add or update the following portions of your cluster configuration file, @/etc/arvados/config.yml@. Refer to "config.defaults.yml":https://dev.arvados.org/projects/arvados/repository/revisions/13996-new-api-config/entry/lib/config/config.defaults.yml for information about additional configuration options.
+Add or update the following portions of your cluster configuration file, @/etc/arvados/config.yml@. Refer to "config.defaults.yml":{{site.baseurl}}/admin/config.html for information about additional configuration options.
 
 <notextile>
 <pre><code>Clusters:
index 593e8018926ad42c0f8a22d6f67fa73c3c1ba7c1..72a80fd834e2c272544de6bae238113f6355032a 100644 (file)
@@ -40,11 +40,9 @@ On a Red Hat-based system, install the following packages:
 
 h2(#configure). Configure Workbench
 
-Edit @/etc/arvados/workbench/application.yml@ following the instructions below.  Workbench reads both @application.yml@ and its own @config/application.defaults.yml@ file.  Values in @application.yml@ take precedence over the defaults that are defined in @config/application.defaults.yml@.  The @config/application.yml.example@ file is not read by Workbench and is provided for installation convenience only.
+Edit @/etc/arvados/config.yml@ to set the keys below.  Only the most important configuration options are listed here.  The full set of configuration options are in the "Workbench section of config.yml":{{site.baseurl}}/admin/config.html
 
-Consult @config/application.default.yml@ for a full list of configuration options.  Always put your local configuration in @/etc/arvados/workbench/application.yml@&mdash;never edit @config/application.default.yml@.
-
-h3. secret_token
+h3. Workbench.SecretKeyBase
 
 This application needs a secret token. Generate a new secret:
 
@@ -54,33 +52,57 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
 </code></pre>
 </notextile>
 
-Then put that value in the @secret_token@ field.
+Then put that value in the @Workbench.SecretKeyBase@ field.
+
+<notextile>
+<pre><code>Cluster:
+  zzzzz:
+    Workbench:
+      SecretKeyBase: <span class="userinput">aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa</span>
+</code></pre>
+</notextile>
 
-h3. arvados_login_base and arvados_v1_base
+h3. Services.Controller.ExternalURL
 
-Point @arvados_login_base@ and @arvados_v1_base@ at your "API server":install-api-server.html. For example like this:
+Ensure that @Services.Controller.ExternalURL@ is configured for "Arvados Controller":install-controller.html . For example like this:
 
 <notextile>
-<pre><code>arvados_login_base: https://prefix_uuid.your.domain/login
-arvados_v1_base: https://prefix_uuid.your.domain/arvados/v1
+<pre><code>Cluster:
+  zzzzz:
+    Services:
+      Controller:
+        ExternalURL: <span class="userinput">https://prefix_uuid.your.domain</span>
 </code></pre>
 </notextile>
 
-h3. site_name
+h3. Workbench.SiteName
+
+@Workbench.SiteName@ can be set to any arbitrary string. It is used to identify this Workbench to people visiting it.
 
-@site_name@ can be set to any arbitrary string. It is used to identify this Workbench to people visiting it.
 
-h3. arvados_insecure_https
+<notextile>
+<pre><code>Cluster:
+  zzzzz:
+    Workbench:
+      SiteName: <span class="userinput">My Arvados</span>
+</code></pre>
+</notextile>
 
-If the SSL certificate you use for your API server isn't an official certificate signed by a CA, make sure @arvados_insecure_https@ is @true@.
+h3. TLS.Insecure
 
-h3. Other options
+For testing only.  Allows use of self-signed certificates.  If true, workbench will not verify the TLS certificate of Arvados Controller.
 
-Consult @application.default.yml@ for a full list of configuration options. Always put your local configuration in @application.yml@ instead of editing @application.default.yml@.
+<notextile>
+<pre><code>Cluster:
+  zzzzz:
+    TLS:
+      Insecure: <span class="userinput">false</span>
+</code></pre>
+</notextile>
 
-h2. Configure Piwik
+h2. Configure Piwik (optional)
 
-In @/var/www/arvados-workbench/current/config@, copy @piwik.yml.example@ to @piwik.yml@ and edit to suit.
+Piwik can be used to gather usage analytics.  In @/var/www/arvados-workbench/current/config@, copy @piwik.yml.example@ to @piwik.yml@ and edit to suit.
 
 h2. Set up Web server
 
@@ -104,7 +126,7 @@ For best performance, we recommend you use Nginx as your Web server front-end, w
   #passenger_ruby /usr/local/rvm/wrappers/default/ruby;
 
   # `client_max_body_size` should match the corresponding setting in
-  # the API server's Nginx configuration.
+  # the API.MaxRequestSize and Controller's server's Nginx configuration.
   client_max_body_size 128m;
 }
 
@@ -124,7 +146,7 @@ server {
 
   index  index.html index.htm index.php;
   # `client_max_body_size` should match the corresponding setting in
-  # the API server's Nginx configuration.
+  # the API.MaxRequestSize and Controller's server's Nginx configuration.
   client_max_body_size 128m;
 
   location / {
index cd70dfd4ae8e44a077572c8a9cc0044905d7b737..e1d25aaa23019020da809943b8309c1b10dc0d07 100644 (file)
@@ -74,4 +74,4 @@ Example:
 
 @arv collection list --filters '[["name", "=", "PGP VAR inputs"], ["created_at", ">=", "2014-10-01"]]'@
 
-will return a list of all collections visible to the current user which are named "PGP VAR inputs" and were created on or after October 1, 2014.
+will return a list of all collections visible to the current user which are named "PGP VAR inputs" and were created on or after October 1, 2014. See the "Common resource methods":{{site.baseurl}}/api/methods.html#index page for more details on using @list@ and @--filters@.
index 1f94ea6da28d26b6b9245ef7840087eceda106fa..35a78695fdb6b2ebf6de195ed5ef7954bc53656f 100644 (file)
@@ -11,7 +11,6 @@ import (
        "fmt"
        "io"
        "os"
-       "os/user"
 
        "git.curoverse.com/arvados.git/lib/cloud"
        "git.curoverse.com/arvados.git/lib/config"
@@ -36,7 +35,7 @@ func (command) RunCommand(prog string, args []string, stdin io.Reader, stdout, s
        flags := flag.NewFlagSet("", flag.ContinueOnError)
        flags.SetOutput(stderr)
        configFile := flags.String("config", arvados.DefaultConfigFile, "Site configuration `file`")
-       instanceSetID := flags.String("instance-set-id", defaultInstanceSetID(), "InstanceSetID tag `value` to use on the test instance")
+       instanceSetID := flags.String("instance-set-id", "zzzzz-zzzzz-zzzzzzcloudtest", "InstanceSetID tag `value` to use on the test instance")
        imageID := flags.String("image-id", "", "Image ID to use when creating the test instance (if empty, use cluster config)")
        instanceType := flags.String("instance-type", "", "Instance type to create (if empty, use cheapest type in config)")
        destroyExisting := flags.Bool("destroy-existing", false, "Destroy any existing instances tagged with our InstanceSetID, instead of erroring out")
@@ -122,15 +121,6 @@ func (command) RunCommand(prog string, args []string, stdin io.Reader, stdout, s
        return 0
 }
 
-func defaultInstanceSetID() string {
-       username := ""
-       if u, err := user.Current(); err == nil {
-               username = u.Username
-       }
-       hostname, _ := os.Hostname()
-       return fmt.Sprintf("cloudtest-%s@%s", username, hostname)
-}
-
 // Return the named instance type, or the cheapest type if name=="".
 func chooseInstanceType(cluster *arvados.Cluster, name string) (arvados.InstanceType, error) {
        if len(cluster.InstanceTypes) == 0 {
index adc57803f1f9432ad1be1e74065a32d56bbd32b2..ad3f70f123d6d4147fc634ef6e121481d3d6cea6 100644 (file)
@@ -69,17 +69,18 @@ func (t *tester) Run() bool {
                return false
        }
 
-       // Don't send the driver any filters the first time we get the
-       // instance list. This way we can log an instance count
-       // (N=...)  that includes all instances in this service
-       // account, even if they don't have the same InstanceSetID.
-       insts, err := t.getInstances(nil)
-       if err != nil {
-               t.Logger.WithError(err).Info("error getting initial list of instances")
-               return false
-       }
-
        for {
+               // Don't send the driver any filters when getting the
+               // initial instance list. This way we can log an
+               // instance count (N=...)  that includes all instances
+               // in this service account, even if they don't have
+               // the same InstanceSetID.
+               insts, err := t.getInstances(nil)
+               if err != nil {
+                       t.Logger.WithError(err).Info("error getting list of instances")
+                       return false
+               }
+
                foundExisting := false
                for _, i := range insts {
                        if i.Tags()[t.TagKeyPrefix+"InstanceSetID"] != string(t.SetID) {
index a41e4b0331548f977d69b3ce993795c51e28ea1d..0351ad02a1923d0a58e8d894885edcbe494ac902 100644 (file)
@@ -146,3 +146,22 @@ func (pl *plainLogger) Warnf(format string, args ...interface{}) {
        pl.used = true
        fmt.Fprintf(pl.w, format+"\n", args...)
 }
+
+var DumpDefaultsCommand defaultsCommand
+
+type defaultsCommand struct{}
+
+func (defaultsCommand) RunCommand(prog string, args []string, stdin io.Reader, stdout, stderr io.Writer) int {
+       var err error
+       defer func() {
+               if err != nil {
+                       fmt.Fprintf(stderr, "%s\n", err)
+               }
+       }()
+
+       _, err = stdout.Write(DefaultYAML)
+       if err != nil {
+               return 1
+       }
+       return 0
+}
index 8e6ed7f2ca3127fc6539b2280914b4ad3b85927d..87ca9d290d57dcd11ac91446e1f454f44ee07ddb 100644 (file)
@@ -48,10 +48,57 @@ Clusters:
         ExternalURL: ""
       WebDAV:
         InternalURLs: {}
+        # Base URL for Workbench inline preview.  If blank, use
+        # WebDAVDownload instead, and disable inline preview.
+        # If both are empty, downloading collections from workbench
+        # will be impossible.
+        #
+        # It is important to properly configure the download service
+        # to migitate cross-site-scripting (XSS) attacks.  A HTML page
+        # can be stored in collection.  If an attacker causes a victim
+        # to visit that page through Workbench, it will be rendered by
+        # the browser.  If all collections are served at the same
+        # domain, the browser will consider collections as coming from
+        # the same origin and having access to the same browsing data,
+        # enabling malicious Javascript on that page to access Arvados
+        # on behalf of the victim.
+        #
+        # This is mitigating by having separate domains for each
+        # collection, or limiting preview to circumstances where the
+        # collection is not accessed with the user's regular
+        # full-access token.
+        #
+        # Serve preview links using uuid or pdh in subdomain
+        # (requires wildcard DNS and TLS certificate)
+        #   https://*.collections.uuid_prefix.arvadosapi.com
+        #
+        # Serve preview links using uuid or pdh in main domain
+        # (requires wildcard DNS and TLS certificate)
+        #   https://*--collections.uuid_prefix.arvadosapi.com
+        #
+        # Serve preview links by setting uuid or pdh in the path.
+        # This configuration only allows previews of public data or
+        # collection-sharing links, because these use the anonymous
+        # user token or the token is already embedded in the URL.
+        # Other data must be handled as downloads via WebDAVDownload:
+        #   https://collections.uuid_prefix.arvadosapi.com
+        #
         ExternalURL: ""
+
       WebDAVDownload:
         InternalURLs: {}
+        # Base URL for download links. If blank, serve links to WebDAV
+        # with disposition=attachment query param.  Unlike preview links,
+        # browsers do not render attachments, so there is no risk of XSS.
+        #
+        # If WebDAVDownload is blank, and WebDAV uses a
+        # single-origin form, then Workbench will show an error page
+        #
+        # Serve download links by setting uuid or pdh in the path:
+        #   https://download.uuid_prefix.arvadosapi.com
+        #
         ExternalURL: ""
+
       Keepstore:
         InternalURLs: {}
         ExternalURL: "-"
@@ -60,6 +107,14 @@ Clusters:
         ExternalURL: ""
       WebShell:
         InternalURLs: {}
+        # ShellInABox service endpoint URL for a given VM.  If empty, do not
+        # offer web shell logins.
+        #
+        # E.g., using a path-based proxy server to forward connections to shell hosts:
+        # https://webshell.uuid_prefix.arvadosapi.com
+        #
+        # E.g., using a name-based proxy server to forward connections to shell hosts:
+        # https://*.webshell.uuid_prefix.arvadosapi.com
         ExternalURL: ""
       Workbench1:
         InternalURLs: {}
@@ -170,6 +225,11 @@ Clusters:
       NewUserNotificationRecipients: []
       NewInactiveUserNotificationRecipients: []
 
+      # Set anonymous_user_token to enable anonymous user access. You can get
+      # the token by running "bundle exec ./script/get_anonymous_user_token.rb"
+      # in the directory where your API server is running.
+      AnonymousUserToken: ""
+
     AuditLogs:
       # Time to keep audit logs, in seconds. (An audit log is a row added
       # to the "logs" table in the PostgreSQL database each time an
@@ -225,7 +285,7 @@ Clusters:
       # one another!
       BlobSigning: true
 
-      # blob_signing_key is a string of alphanumeric characters used to
+      # BlobSigningKey is a string of alphanumeric characters used to
       # generate permission signatures for Keep locators. It must be
       # identical to the permission key given to Keep. IMPORTANT: This is
       # a site secret. It should be at least 50 characters.
@@ -293,6 +353,19 @@ Clusters:
       ManagedProperties:
         SAMPLE: {Function: original_owner, Protected: true}
 
+      # In "trust all content" mode, Workbench will redirect download
+      # requests to WebDAV preview link, even in the cases when
+      # WebDAV would have to expose XSS vulnerabilities in order to
+      # handle the redirect (see discussion on Services.WebDAV).
+      #
+      # This setting has no effect in the recommended configuration,
+      # where the WebDAV is configured to have a separate domain for
+      # every collection; in this case XSS protection is provided by
+      # browsers' same-origin policy.
+      #
+      # The default setting (false) is appropriate for a multi-user site.
+      TrustAllContent: false
+
     Login:
       # These settings are provided by your OAuth2 provider (e.g.,
       # sso-provider).
@@ -613,11 +686,15 @@ Clusters:
     Mail:
       MailchimpAPIKey: ""
       MailchimpListID: ""
-      SendUserSetupNotificationEmail: ""
-      IssueReporterEmailFrom: ""
-      IssueReporterEmailTo: ""
-      SupportEmailAddress: ""
-      EmailFrom: ""
+      SendUserSetupNotificationEmail: true
+
+      # Bug/issue report notification to and from addresses
+      IssueReporterEmailFrom: "arvados@example.com"
+      IssueReporterEmailTo: "arvados@example.com"
+      SupportEmailAddress: "arvados@example.com"
+
+      # Generic issue email from
+      EmailFrom: "arvados@example.com"
     RemoteClusters:
       "*":
         Host: ""
@@ -651,16 +728,51 @@ Clusters:
       ArvadosDocsite: https://doc.arvados.org
       ArvadosPublicDataDocURL: https://playground.arvados.org/projects/public
       ShowUserAgreementInline: false
-      SecretToken: ""
       SecretKeyBase: ""
+
+      # Scratch directory used by the remote repository browsing
+      # feature. If it doesn't exist, it (and any missing parents) will be
+      # created using mkdir_p.
       RepositoryCache: /var/www/arvados-workbench/current/tmp/git
-      UserProfileFormFields:
-        SAMPLE:
-          Type: text
-          FormFieldTitle: ""
-          FormFieldDescription: ""
-          Required: true
+
+      # Below is a sample setting of user_profile_form_fields config parameter.
+      # This configuration parameter should be set to either false (to disable) or
+      # to a map as shown below.
+      # Configure the map of input fields to be displayed in the profile page
+      # using the attribute "key" for each of the input fields.
+      # This sample shows configuration with one required and one optional form fields.
+      # For each of these input fields:
+      #   You can specify "Type" as "text" or "select".
+      #   List the "Options" to be displayed for each of the "select" menu.
+      #   Set "Required" as "true" for any of these fields to make them required.
+      # If any of the required fields are missing in the user's profile, the user will be
+      # redirected to the profile page before they can access any Workbench features.
+      UserProfileFormFields: {}
+        # exampleTextValue:  # key that will be set in properties
+        #   Type: text  #
+        #   FormFieldTitle: ""
+        #   FormFieldDescription: ""
+        #   Required: true
+        #   Position: 1
+        # exampleOptionsValue:
+        #   Type: select
+        #   FormFieldTitle: ""
+        #   FormFieldDescription: ""
+        #   Required: true
+        #   Position: 1
+        #   Options:
+        #     red: {}
+        #     blue: {}
+        #     yellow: {}
+
+      # Use "UserProfileFormMessage to configure the message you want
+      # to display on the profile page.
       UserProfileFormMessage: 'Welcome to Arvados. All <span style="color:red">required fields</span> must be completed before you can proceed.'
+
+      # Mimetypes of applications for which the view icon
+      # would be enabled in a collection's show page.
+      # It is sufficient to list only applications here.
+      # No need to list text and image types.
       ApplicationMimetypesWithViewIcon:
         cwl: {}
         fasta: {}
@@ -677,18 +789,50 @@ Clusters:
         vnd.realvnc.bed: {}
         xml: {}
         xsl: {}
+
+      # The maximum number of bytes to load in the log viewer
       LogViewerMaxBytes: 1M
+
+      # When anonymous_user_token is configured, show public projects page
       EnablePublicProjectsPage: true
+
+      # By default, disable the "Getting Started" popup which is specific to Arvados playground
       EnableGettingStartedPopup: false
+
+      # Ask Arvados API server to compress its response payloads.
       APIResponseCompression: true
+
+      # Timeouts for API requests.
       APIClientConnectTimeout: 2m
       APIClientReceiveTimeout: 5m
+
+      # Maximum number of historic log records of a running job to fetch
+      # and display in the Log tab, while subscribing to web sockets.
       RunningJobLogRecordsToFetch: 2000
+
+      # In systems with many shared projects, loading of dashboard and topnav
+      # cab be slow due to collections indexing; use the following parameters
+      # to suppress these properties
       ShowRecentCollectionsOnDashboard: true
       ShowUserNotifications: true
-      MultiSiteSearch: false
+
+      # Enable/disable "multi-site search" in top nav ("true"/"false"), or
+      # a link to the multi-site search page on a "home" Workbench site.
+      #
+      # Example:
+      #   https://workbench.qr1hi.arvadosapi.com/collections/multisite
+      MultiSiteSearch: ""
+
+      # Should workbench allow management of local git repositories? Set to false if
+      # the jobs api is disabled and there are no local git repositories.
       Repositories: true
+
       SiteName: Arvados Workbench
+      ProfilingEnabled: false
+
+      # This is related to obsolete Google OpenID 1.0 login
+      # but some workbench stuff still expects it to be set.
+      DefaultOpenIdPrefix: "https://www.google.com/accounts/o8/id"
 
       # Workbench2 configs
       VocabularyURL: ""
index faf542e6f773c6192779c7aa4dbb5ed0675fe0c5..b79dec4d9d1532b1f348965e5c657e71df21704e 100644 (file)
@@ -55,77 +55,122 @@ func ExportJSON(w io.Writer, cluster *arvados.Cluster) error {
 // exists.
 var whitelist = map[string]bool{
        // | sort -t'"' -k2,2
-       "API":                                        true,
-       "API.AsyncPermissionsUpdateInterval":         false,
-       "API.DisabledAPIs":                           false,
-       "API.MaxIndexDatabaseRead":                   false,
-       "API.MaxItemsPerResponse":                    true,
-       "API.MaxRequestAmplification":                false,
-       "API.MaxRequestSize":                         true,
-       "API.RailsSessionSecretToken":                false,
-       "API.RequestTimeout":                         true,
-       "AuditLogs":                                  false,
-       "AuditLogs.MaxAge":                           false,
-       "AuditLogs.MaxDeleteBatch":                   false,
-       "AuditLogs.UnloggedAttributes":               false,
-       "Collections":                                true,
-       "Collections.BlobSigning":                    true,
-       "Collections.BlobSigningKey":                 false,
-       "Collections.BlobSigningTTL":                 true,
-       "Collections.CollectionVersioning":           false,
-       "Collections.DefaultReplication":             true,
-       "Collections.DefaultTrashLifetime":           true,
-       "Collections.ManagedProperties":              true,
-       "Collections.ManagedProperties.*":            true,
-       "Collections.ManagedProperties.*.*":          true,
-       "Collections.PreserveVersionIfIdle":          true,
-       "Collections.TrashSweepInterval":             false,
-       "Containers":                                 true,
-       "Containers.CloudVMs":                        false,
-       "Containers.DefaultKeepCacheRAM":             true,
-       "Containers.DispatchPrivateKey":              false,
-       "Containers.JobsAPI":                         true,
-       "Containers.JobsAPI.CrunchJobUser":           false,
-       "Containers.JobsAPI.CrunchJobWrapper":        false,
-       "Containers.JobsAPI.CrunchRefreshTrigger":    false,
-       "Containers.JobsAPI.DefaultDockerImage":      false,
-       "Containers.JobsAPI.Enable":                  true,
-       "Containers.JobsAPI.GitInternalDir":          false,
-       "Containers.JobsAPI.ReuseJobIfOutputsDiffer": false,
-       "Containers.Logging":                         false,
-       "Containers.LogReuseDecisions":               false,
-       "Containers.MaxComputeVMs":                   false,
-       "Containers.MaxDispatchAttempts":             false,
-       "Containers.MaxRetryAttempts":                true,
-       "Containers.SLURM":                           false,
-       "Containers.StaleLockTimeout":                false,
-       "Containers.SupportedDockerImageFormats":     true,
-       "Containers.UsePreemptibleInstances":         true,
-       "EnableBetaController14287":                  false,
-       "Git":                                        false,
-       "InstanceTypes":                              true,
-       "InstanceTypes.*":                            true,
-       "InstanceTypes.*.*":                          true,
-       "Login":                                      false,
-       "Mail":                                       false,
-       "ManagementToken":                            false,
-       "PostgreSQL":                                 false,
-       "RemoteClusters":                             true,
-       "RemoteClusters.*":                           true,
-       "RemoteClusters.*.ActivateUsers":             true,
-       "RemoteClusters.*.Host":                      true,
-       "RemoteClusters.*.Insecure":                  true,
-       "RemoteClusters.*.Proxy":                     true,
-       "RemoteClusters.*.Scheme":                    true,
-       "Services":                                   true,
-       "Services.*":                                 true,
-       "Services.*.ExternalURL":                     true,
-       "Services.*.InternalURLs":                    false,
-       "SystemLogs":                                 false,
-       "SystemRootToken":                            false,
-       "TLS":                                        false,
-       "Users":                                      false,
-       "Workbench":                                  false,
+       "API":                                          true,
+       "API.AsyncPermissionsUpdateInterval":           false,
+       "API.DisabledAPIs":                             false,
+       "API.MaxIndexDatabaseRead":                     false,
+       "API.MaxItemsPerResponse":                      true,
+       "API.MaxRequestAmplification":                  false,
+       "API.MaxRequestSize":                           true,
+       "API.RailsSessionSecretToken":                  false,
+       "API.RequestTimeout":                           true,
+       "AuditLogs":                                    false,
+       "AuditLogs.MaxAge":                             false,
+       "AuditLogs.MaxDeleteBatch":                     false,
+       "AuditLogs.UnloggedAttributes":                 false,
+       "Collections":                                  true,
+       "Collections.BlobSigning":                      true,
+       "Collections.BlobSigningKey":                   false,
+       "Collections.BlobSigningTTL":                   true,
+       "Collections.CollectionVersioning":             false,
+       "Collections.DefaultReplication":               true,
+       "Collections.DefaultTrashLifetime":             true,
+       "Collections.ManagedProperties":                true,
+       "Collections.ManagedProperties.*":              true,
+       "Collections.ManagedProperties.*.*":            true,
+       "Collections.PreserveVersionIfIdle":            true,
+       "Collections.TrashSweepInterval":               false,
+       "Collections.TrustAllContent":                  false,
+       "Containers":                                   true,
+       "Containers.CloudVMs":                          false,
+       "Containers.DefaultKeepCacheRAM":               true,
+       "Containers.DispatchPrivateKey":                false,
+       "Containers.JobsAPI":                           true,
+       "Containers.JobsAPI.CrunchJobUser":             false,
+       "Containers.JobsAPI.CrunchJobWrapper":          false,
+       "Containers.JobsAPI.CrunchRefreshTrigger":      false,
+       "Containers.JobsAPI.DefaultDockerImage":        false,
+       "Containers.JobsAPI.Enable":                    true,
+       "Containers.JobsAPI.GitInternalDir":            false,
+       "Containers.JobsAPI.ReuseJobIfOutputsDiffer":   false,
+       "Containers.Logging":                           false,
+       "Containers.LogReuseDecisions":                 false,
+       "Containers.MaxComputeVMs":                     false,
+       "Containers.MaxDispatchAttempts":               false,
+       "Containers.MaxRetryAttempts":                  true,
+       "Containers.SLURM":                             false,
+       "Containers.StaleLockTimeout":                  false,
+       "Containers.SupportedDockerImageFormats":       true,
+       "Containers.UsePreemptibleInstances":           true,
+       "EnableBetaController14287":                    false,
+       "Git":                                          false,
+       "InstanceTypes":                                true,
+       "InstanceTypes.*":                              true,
+       "InstanceTypes.*.*":                            true,
+       "Login":                                        false,
+       "Mail":                                         false,
+       "ManagementToken":                              false,
+       "PostgreSQL":                                   false,
+       "RemoteClusters":                               true,
+       "RemoteClusters.*":                             true,
+       "RemoteClusters.*.ActivateUsers":               true,
+       "RemoteClusters.*.Host":                        true,
+       "RemoteClusters.*.Insecure":                    true,
+       "RemoteClusters.*.Proxy":                       true,
+       "RemoteClusters.*.Scheme":                      true,
+       "Services":                                     true,
+       "Services.*":                                   true,
+       "Services.*.ExternalURL":                       true,
+       "Services.*.InternalURLs":                      false,
+       "SystemLogs":                                   false,
+       "SystemRootToken":                              false,
+       "TLS":                                          false,
+       "Users":                                        true,
+       "Users.AnonymousUserToken":                     true,
+       "Users.AdminNotifierEmailFrom":                 false,
+       "Users.AutoAdminFirstUser":                     false,
+       "Users.AutoAdminUserWithEmail":                 false,
+       "Users.AutoSetupNewUsers":                      false,
+       "Users.AutoSetupNewUsersWithRepository":        false,
+       "Users.AutoSetupNewUsersWithVmUUID":            false,
+       "Users.AutoSetupUsernameBlacklist":             false,
+       "Users.EmailSubjectPrefix":                     false,
+       "Users.NewInactiveUserNotificationRecipients":  false,
+       "Users.NewUserNotificationRecipients":          false,
+       "Users.NewUsersAreActive":                      false,
+       "Users.UserNotifierEmailFrom":                  false,
+       "Users.UserProfileNotificationAddress":         false,
+       "Workbench":                                    true,
+       "Workbench.ActivationContactLink":              false,
+       "Workbench.APIClientConnectTimeout":            true,
+       "Workbench.APIClientReceiveTimeout":            true,
+       "Workbench.APIResponseCompression":             true,
+       "Workbench.ApplicationMimetypesWithViewIcon":   true,
+       "Workbench.ApplicationMimetypesWithViewIcon.*": true,
+       "Workbench.ArvadosDocsite":                     true,
+       "Workbench.ArvadosPublicDataDocURL":            true,
+       "Workbench.DefaultOpenIdPrefix":                false,
+       "Workbench.EnableGettingStartedPopup":          true,
+       "Workbench.EnablePublicProjectsPage":           true,
+       "Workbench.FileViewersConfigURL":               true,
+       "Workbench.LogViewerMaxBytes":                  true,
+       "Workbench.MultiSiteSearch":                    true,
+       "Workbench.ProfilingEnabled":                   true,
+       "Workbench.Repositories":                       false,
+       "Workbench.RepositoryCache":                    false,
+       "Workbench.RunningJobLogRecordsToFetch":        true,
+       "Workbench.SecretKeyBase":                      false,
+       "Workbench.ShowRecentCollectionsOnDashboard":   true,
+       "Workbench.ShowUserAgreementInline":            true,
+       "Workbench.ShowUserNotifications":              true,
+       "Workbench.SiteName":                           true,
+       "Workbench.Theme":                              true,
+       "Workbench.UserProfileFormFields":              true,
+       "Workbench.UserProfileFormFields.*":            true,
+       "Workbench.UserProfileFormFields.*.*":          true,
+       "Workbench.UserProfileFormFields.*.*.*":        true,
+       "Workbench.UserProfileFormMessage":             true,
+       "Workbench.VocabularyURL":                      true,
 }
 
 func redactUnsafe(m map[string]interface{}, mPrefix, lookupPrefix string) error {
index 5e5222d11e28b9265d1270befb30cf4d92c9feea..35443b2bd47c412e7f7e71a92ee1f029e401b991 100644 (file)
@@ -54,10 +54,57 @@ Clusters:
         ExternalURL: ""
       WebDAV:
         InternalURLs: {}
+        # Base URL for Workbench inline preview.  If blank, use
+        # WebDAVDownload instead, and disable inline preview.
+        # If both are empty, downloading collections from workbench
+        # will be impossible.
+        #
+        # It is important to properly configure the download service
+        # to migitate cross-site-scripting (XSS) attacks.  A HTML page
+        # can be stored in collection.  If an attacker causes a victim
+        # to visit that page through Workbench, it will be rendered by
+        # the browser.  If all collections are served at the same
+        # domain, the browser will consider collections as coming from
+        # the same origin and having access to the same browsing data,
+        # enabling malicious Javascript on that page to access Arvados
+        # on behalf of the victim.
+        #
+        # This is mitigating by having separate domains for each
+        # collection, or limiting preview to circumstances where the
+        # collection is not accessed with the user's regular
+        # full-access token.
+        #
+        # Serve preview links using uuid or pdh in subdomain
+        # (requires wildcard DNS and TLS certificate)
+        #   https://*.collections.uuid_prefix.arvadosapi.com
+        #
+        # Serve preview links using uuid or pdh in main domain
+        # (requires wildcard DNS and TLS certificate)
+        #   https://*--collections.uuid_prefix.arvadosapi.com
+        #
+        # Serve preview links by setting uuid or pdh in the path.
+        # This configuration only allows previews of public data or
+        # collection-sharing links, because these use the anonymous
+        # user token or the token is already embedded in the URL.
+        # Other data must be handled as downloads via WebDAVDownload:
+        #   https://collections.uuid_prefix.arvadosapi.com
+        #
         ExternalURL: ""
+
       WebDAVDownload:
         InternalURLs: {}
+        # Base URL for download links. If blank, serve links to WebDAV
+        # with disposition=attachment query param.  Unlike preview links,
+        # browsers do not render attachments, so there is no risk of XSS.
+        #
+        # If WebDAVDownload is blank, and WebDAV uses a
+        # single-origin form, then Workbench will show an error page
+        #
+        # Serve download links by setting uuid or pdh in the path:
+        #   https://download.uuid_prefix.arvadosapi.com
+        #
         ExternalURL: ""
+
       Keepstore:
         InternalURLs: {}
         ExternalURL: "-"
@@ -66,6 +113,14 @@ Clusters:
         ExternalURL: ""
       WebShell:
         InternalURLs: {}
+        # ShellInABox service endpoint URL for a given VM.  If empty, do not
+        # offer web shell logins.
+        #
+        # E.g., using a path-based proxy server to forward connections to shell hosts:
+        # https://webshell.uuid_prefix.arvadosapi.com
+        #
+        # E.g., using a name-based proxy server to forward connections to shell hosts:
+        # https://*.webshell.uuid_prefix.arvadosapi.com
         ExternalURL: ""
       Workbench1:
         InternalURLs: {}
@@ -176,6 +231,11 @@ Clusters:
       NewUserNotificationRecipients: []
       NewInactiveUserNotificationRecipients: []
 
+      # Set anonymous_user_token to enable anonymous user access. You can get
+      # the token by running "bundle exec ./script/get_anonymous_user_token.rb"
+      # in the directory where your API server is running.
+      AnonymousUserToken: ""
+
     AuditLogs:
       # Time to keep audit logs, in seconds. (An audit log is a row added
       # to the "logs" table in the PostgreSQL database each time an
@@ -231,7 +291,7 @@ Clusters:
       # one another!
       BlobSigning: true
 
-      # blob_signing_key is a string of alphanumeric characters used to
+      # BlobSigningKey is a string of alphanumeric characters used to
       # generate permission signatures for Keep locators. It must be
       # identical to the permission key given to Keep. IMPORTANT: This is
       # a site secret. It should be at least 50 characters.
@@ -299,6 +359,19 @@ Clusters:
       ManagedProperties:
         SAMPLE: {Function: original_owner, Protected: true}
 
+      # In "trust all content" mode, Workbench will redirect download
+      # requests to WebDAV preview link, even in the cases when
+      # WebDAV would have to expose XSS vulnerabilities in order to
+      # handle the redirect (see discussion on Services.WebDAV).
+      #
+      # This setting has no effect in the recommended configuration,
+      # where the WebDAV is configured to have a separate domain for
+      # every collection; in this case XSS protection is provided by
+      # browsers' same-origin policy.
+      #
+      # The default setting (false) is appropriate for a multi-user site.
+      TrustAllContent: false
+
     Login:
       # These settings are provided by your OAuth2 provider (e.g.,
       # sso-provider).
@@ -619,11 +692,15 @@ Clusters:
     Mail:
       MailchimpAPIKey: ""
       MailchimpListID: ""
-      SendUserSetupNotificationEmail: ""
-      IssueReporterEmailFrom: ""
-      IssueReporterEmailTo: ""
-      SupportEmailAddress: ""
-      EmailFrom: ""
+      SendUserSetupNotificationEmail: true
+
+      # Bug/issue report notification to and from addresses
+      IssueReporterEmailFrom: "arvados@example.com"
+      IssueReporterEmailTo: "arvados@example.com"
+      SupportEmailAddress: "arvados@example.com"
+
+      # Generic issue email from
+      EmailFrom: "arvados@example.com"
     RemoteClusters:
       "*":
         Host: ""
@@ -657,16 +734,51 @@ Clusters:
       ArvadosDocsite: https://doc.arvados.org
       ArvadosPublicDataDocURL: https://playground.arvados.org/projects/public
       ShowUserAgreementInline: false
-      SecretToken: ""
       SecretKeyBase: ""
+
+      # Scratch directory used by the remote repository browsing
+      # feature. If it doesn't exist, it (and any missing parents) will be
+      # created using mkdir_p.
       RepositoryCache: /var/www/arvados-workbench/current/tmp/git
-      UserProfileFormFields:
-        SAMPLE:
-          Type: text
-          FormFieldTitle: ""
-          FormFieldDescription: ""
-          Required: true
+
+      # Below is a sample setting of user_profile_form_fields config parameter.
+      # This configuration parameter should be set to either false (to disable) or
+      # to a map as shown below.
+      # Configure the map of input fields to be displayed in the profile page
+      # using the attribute "key" for each of the input fields.
+      # This sample shows configuration with one required and one optional form fields.
+      # For each of these input fields:
+      #   You can specify "Type" as "text" or "select".
+      #   List the "Options" to be displayed for each of the "select" menu.
+      #   Set "Required" as "true" for any of these fields to make them required.
+      # If any of the required fields are missing in the user's profile, the user will be
+      # redirected to the profile page before they can access any Workbench features.
+      UserProfileFormFields: {}
+        # exampleTextValue:  # key that will be set in properties
+        #   Type: text  #
+        #   FormFieldTitle: ""
+        #   FormFieldDescription: ""
+        #   Required: true
+        #   Position: 1
+        # exampleOptionsValue:
+        #   Type: select
+        #   FormFieldTitle: ""
+        #   FormFieldDescription: ""
+        #   Required: true
+        #   Position: 1
+        #   Options:
+        #     red: {}
+        #     blue: {}
+        #     yellow: {}
+
+      # Use "UserProfileFormMessage to configure the message you want
+      # to display on the profile page.
       UserProfileFormMessage: 'Welcome to Arvados. All <span style="color:red">required fields</span> must be completed before you can proceed.'
+
+      # Mimetypes of applications for which the view icon
+      # would be enabled in a collection's show page.
+      # It is sufficient to list only applications here.
+      # No need to list text and image types.
       ApplicationMimetypesWithViewIcon:
         cwl: {}
         fasta: {}
@@ -683,18 +795,50 @@ Clusters:
         vnd.realvnc.bed: {}
         xml: {}
         xsl: {}
+
+      # The maximum number of bytes to load in the log viewer
       LogViewerMaxBytes: 1M
+
+      # When anonymous_user_token is configured, show public projects page
       EnablePublicProjectsPage: true
+
+      # By default, disable the "Getting Started" popup which is specific to Arvados playground
       EnableGettingStartedPopup: false
+
+      # Ask Arvados API server to compress its response payloads.
       APIResponseCompression: true
+
+      # Timeouts for API requests.
       APIClientConnectTimeout: 2m
       APIClientReceiveTimeout: 5m
+
+      # Maximum number of historic log records of a running job to fetch
+      # and display in the Log tab, while subscribing to web sockets.
       RunningJobLogRecordsToFetch: 2000
+
+      # In systems with many shared projects, loading of dashboard and topnav
+      # cab be slow due to collections indexing; use the following parameters
+      # to suppress these properties
       ShowRecentCollectionsOnDashboard: true
       ShowUserNotifications: true
-      MultiSiteSearch: false
+
+      # Enable/disable "multi-site search" in top nav ("true"/"false"), or
+      # a link to the multi-site search page on a "home" Workbench site.
+      #
+      # Example:
+      #   https://workbench.qr1hi.arvadosapi.com/collections/multisite
+      MultiSiteSearch: ""
+
+      # Should workbench allow management of local git repositories? Set to false if
+      # the jobs api is disabled and there are no local git repositories.
       Repositories: true
+
       SiteName: Arvados Workbench
+      ProfilingEnabled: false
+
+      # This is related to obsolete Google OpenID 1.0 login
+      # but some workbench stuff still expects it to be set.
+      DefaultOpenIdPrefix: "https://www.google.com/accounts/o8/id"
 
       # Workbench2 configs
       VocabularyURL: ""
index 252ca57d47bb30ad1834e7070b3cfdf1e0ffdbb1..c1ea586b0475db4c5b1a780fea5eab11bb02d11f 100644 (file)
@@ -133,10 +133,10 @@ class CollectionFsAccess(cwltool.stdfsaccess.StdFsAccess):
         patternsegments = rest.split("/")
         return sorted(self._match(collection, patternsegments, "keep:" + collection.manifest_locator()))
 
-    def open(self, fn, mode):
+    def open(self, fn, mode, encoding=None):
         collection, rest = self.get_collection(fn)
         if collection is not None:
-            return collection.open(rest, mode)
+            return collection.open(rest, mode, encoding=encoding)
         else:
             return super(CollectionFsAccess, self).open(self._abs(fn), mode)
 
@@ -225,7 +225,7 @@ class CollectionFetcher(DefaultFetcher):
 
     def fetch_text(self, url):
         if url.startswith("keep:"):
-            with self.fsaccess.open(url, "r") as f:
+            with self.fsaccess.open(url, "r", encoding="utf-8") as f:
                 return f.read()
         if url.startswith("arvwf:"):
             record = self.api_client.workflows().get(uuid=url[6:]).execute(num_retries=self.num_retries)
index 799f2e996c1af741515f26d0543a25edf95f4a7a..9c667610bcaaafc97ba276c4c25e632e6eb1c881 100644 (file)
@@ -85,6 +85,7 @@ type Cluster struct {
                ManagedProperties     map[string]interface{}
                PreserveVersionIfIdle Duration
                TrashSweepInterval    Duration
+               TrustAllContent       bool
        }
        Git struct {
                Repositories string
@@ -96,7 +97,7 @@ type Cluster struct {
        Mail struct {
                MailchimpAPIKey                string
                MailchimpListID                string
-               SendUserSetupNotificationEmail string
+               SendUserSetupNotificationEmail bool
                IssueReporterEmailFrom         string
                IssueReporterEmailTo           string
                SupportEmailAddress            string
@@ -113,6 +114,7 @@ type Cluster struct {
                Insecure    bool
        }
        Users struct {
+               AnonymousUserToken                    string
                AdminNotifierEmailFrom                string
                AutoAdminFirstUser                    bool
                AutoAdminUserWithEmail                string
@@ -135,16 +137,17 @@ type Cluster struct {
                ApplicationMimetypesWithViewIcon map[string]struct{}
                ArvadosDocsite                   string
                ArvadosPublicDataDocURL          string
+               DefaultOpenIdPrefix              string
                EnableGettingStartedPopup        bool
                EnablePublicProjectsPage         bool
                FileViewersConfigURL             string
                LogViewerMaxBytes                ByteSize
-               MultiSiteSearch                  bool
+               MultiSiteSearch                  string
+               ProfilingEnabled                 bool
                Repositories                     bool
                RepositoryCache                  string
                RunningJobLogRecordsToFetch      int
                SecretKeyBase                    string
-               SecretToken                      string
                ShowRecentCollectionsOnDashboard bool
                ShowUserAgreementInline          bool
                ShowUserNotifications            bool
@@ -155,6 +158,8 @@ type Cluster struct {
                        FormFieldTitle       string
                        FormFieldDescription string
                        Required             bool
+                       Position             int
+                       Options              map[string]struct{}
                }
                UserProfileFormMessage string
                VocabularyURL          string
index 22a8fed58e2fc584333f5f3684e822a7a20ac21c..cf4b842c4a93cef5900c66aa67cbfd259bb031db 100644 (file)
@@ -17,6 +17,7 @@
 # delete application.yml and database.yml.
 
 require 'config_loader'
+require 'open3'
 
 begin
   # If secret_token.rb exists here, we need to load it first.
@@ -42,34 +43,31 @@ EOS
   WARNED_OMNIAUTH_CONFIG = true
 end
 
-# Load the defaults
-$arvados_config_defaults = ConfigLoader.load "#{::Rails.root.to_s}/config/config.default.yml"
-if $arvados_config_defaults.empty?
-  raise "Missing #{::Rails.root.to_s}/config/config.default.yml"
-end
-
-def remove_sample_entries(h)
-  return unless h.is_a? Hash
-  h.delete("SAMPLE")
-  h.each { |k, v| remove_sample_entries(v) }
+# Load the defaults, used by config:migrate and fallback loading
+# legacy application.yml
+Open3.popen2("arvados-server", "config-dump", "-config=-") do |stdin, stdout, status_thread|
+  stdin.write("Clusters: {xxxxx: {}}")
+  stdin.close
+  confs = YAML.load(stdout, deserialize_symbols: false)
+  clusterID, clusterConfig = confs["Clusters"].first
+  $arvados_config_defaults = clusterConfig
+  $arvados_config_defaults["ClusterID"] = clusterID
 end
-remove_sample_entries($arvados_config_defaults)
-
-clusterID, clusterConfig = $arvados_config_defaults["Clusters"].first
-$arvados_config_defaults = clusterConfig
-$arvados_config_defaults["ClusterID"] = clusterID
-
-# Initialize the global config with the defaults
-$arvados_config_global = $arvados_config_defaults.deep_dup
 
 # Load the global config file
-confs = ConfigLoader.load "/etc/arvados/config.yml"
-if !confs.empty?
-  clusterID, clusterConfig = confs["Clusters"].first
-  $arvados_config_global["ClusterID"] = clusterID
-
-  # Copy the cluster config over the defaults
-  $arvados_config_global.deep_merge!(clusterConfig)
+Open3.popen2("arvados-server", "config-dump") do |stdin, stdout, status_thread|
+  confs = YAML.load(stdout, deserialize_symbols: false)
+  if confs && !confs.empty?
+    # config-dump merges defaults with user configuration, so every
+    # key should be set.
+    clusterID, clusterConfig = confs["Clusters"].first
+    $arvados_config_global = clusterConfig
+    $arvados_config_global["ClusterID"] = clusterID
+  else
+    # config-dump failed, assume we will be loading from legacy
+    # application.yml, initialize with defaults.
+    $arvados_config_global = $arvados_config_defaults.deep_dup
+  end
 end
 
 # Now make a copy
diff --git a/services/api/config/config.default.yml b/services/api/config/config.default.yml
deleted file mode 120000 (symlink)
index f039aa0..0000000
+++ /dev/null
@@ -1 +0,0 @@
-../../../lib/config/config.default.yml
\ No newline at end of file
index 1d5891ed62832e4fc761e7005122f5d2b0785fcd..47e1e4bb178f2d0bd3f6d99dec1c23458bcd2ff0 100644 (file)
@@ -6,9 +6,9 @@ fpm_depends+=('git >= 1.7.10')
 
 case "$TARGET" in
     centos*)
-        fpm_depends+=(libcurl-devel postgresql-devel)
+        fpm_depends+=(libcurl-devel postgresql-devel arvados-server)
         ;;
     debian* | ubuntu*)
-        fpm_depends+=(libcurl-ssl-dev libpq-dev g++)
+        fpm_depends+=(libcurl-ssl-dev libpq-dev g++ arvados-server)
         ;;
 esac
index d03512d5989b4f950d7169db58e6cd6feefbf2ed..eff59d2f72104407615302109bd6967e3a9b3fff 100644 (file)
@@ -1,7 +1,7 @@
 PATH
   remote: .
   specs:
-    arvados-login-sync (1.3.3.20190528194843)
+    arvados-login-sync (1.4.0.20190701162225)
       arvados (~> 1.3.0, >= 1.3.0)
 
 GEM
@@ -60,8 +60,8 @@ GEM
     mocha (1.8.0)
       metaclass (~> 0.0.1)
     multi_json (1.13.1)
-    multipart-post (2.1.1)
-    os (1.0.1)
+    multipart-post (2.0.0)
+    os (1.0.0)
     public_suffix (3.0.3)
     rake (12.3.2)
     retriable (1.4.1)
index efcad7f44c976e5118027e87e4e4d8d0ac100f5d..0a0d82e71b59c4c0290457e85aaf2b33480b28c2 100755 (executable)
@@ -560,7 +560,18 @@ case "$subcmd" in
 
     clone)
         if test -n "$2" ; then
-            cp -r "$ARVBOX_BASE/$1" "$ARVBOX_BASE/$2"
+           mkdir -p "$ARVBOX_BASE/$2"
+            cp -a "$ARVBOX_BASE/$1/passenger" \
+              "$ARVBOX_BASE/$1/gems" \
+              "$ARVBOX_BASE/$1/pip" \
+              "$ARVBOX_BASE/$1/npm" \
+              "$ARVBOX_BASE/$1/gopath" \
+              "$ARVBOX_BASE/$1/Rlibs" \
+              "$ARVBOX_BASE/$1/arvados" \
+              "$ARVBOX_BASE/$1/sso-devise-omniauth-provider" \
+              "$ARVBOX_BASE/$1/composer" \
+              "$ARVBOX_BASE/$1/workbench2" \
+              "$ARVBOX_BASE/$2"
             echo "Created new arvbox $2"
             echo "export ARVBOX_CONTAINER=$2"
         else
index a64f2f928e62f23a868d81b2fa9ed7952eef901d..f6191d63f429300b4d9c590dad78cf7eea5e3c68 100755 (executable)
@@ -45,6 +45,19 @@ else
     echo $vm_uuid > /var/lib/arvados/vm-uuid
 fi
 
+if ! test -f /var/lib/arvados/api_database_pw ; then
+    ruby -e 'puts rand(2**128).to_s(36)' > /var/lib/arvados/api_database_pw
+fi
+database_pw=$(cat /var/lib/arvados/api_database_pw)
+
+if ! (psql postgres -c "\du" | grep "^ arvados ") >/dev/null ; then
+    psql postgres -c "create user arvados with password '$database_pw'"
+fi
+psql postgres -c "ALTER USER arvados WITH SUPERUSER;"
+
+if test -a /usr/src/arvados/services/api/config/arvados_config.rb ; then
+    rm -f config/application.yml config/database.yml
+else
 cat >config/application.yml <<EOF
 $RAILS_ENV:
   uuid_prefix: $uuid_prefix
@@ -70,18 +83,8 @@ $RAILS_ENV:
 EOF
 
 (cd config && /usr/local/lib/arvbox/yml_override.py application.yml)
-
-if ! test -f /var/lib/arvados/api_database_pw ; then
-    ruby -e 'puts rand(2**128).to_s(36)' > /var/lib/arvados/api_database_pw
-fi
-database_pw=$(cat /var/lib/arvados/api_database_pw)
-
-if ! (psql postgres -c "\du" | grep "^ arvados ") >/dev/null ; then
-    psql postgres -c "create user arvados with password '$database_pw'"
-fi
-psql postgres -c "ALTER USER arvados WITH SUPERUSER;"
-
 sed "s/password:.*/password: $database_pw/" <config/database.yml.example >config/database.yml
+fi
 
 if ! test -f /var/lib/arvados/api_database_setup ; then
    bundle exec rake db:setup
index 799fc63e1c02e13d500a31a67f59b9a0611f0f54..4cc96e8b7ca3a132056f2483bf9ea522a7396fce 100755 (executable)
@@ -23,6 +23,8 @@ sso_app_secret=$(cat /var/lib/arvados/sso_app_secret)
 vm_uuid=$(cat /var/lib/arvados/vm-uuid)
 database_pw=$(cat /var/lib/arvados/api_database_pw)
 
+workbench_secret_key_base=$(cat /var/lib/arvados/workbench_secret_token)
+
 if test -s /var/lib/arvados/api_rails_env ; then
   database_env=$(cat /var/lib/arvados/api_rails_env)
 else
@@ -50,6 +52,10 @@ Clusters:
         ExternalURL: "http://$localip:${services[arv-git-httpd]}/"
       WebDAV:
         ExternalURL: "https://$localip:${services[keep-web-ssl]}/"
+      Composer:
+        ExternalURL: "http://$localip:${services[composer]}"
+      Controller:
+        ExternalURL: "https://$localip:${services[controller-ssl]}"
     NodeProfiles:  # to be deprecated in favor of "Services" section
       "*":
         arvados-controller:
@@ -82,6 +88,9 @@ Clusters:
       AutoSetupNewUsers: true
       AutoSetupNewUsersWithVmUUID: $vm_uuid
       AutoSetupNewUsersWithRepository: true
+    Workbench:
+      SecretKeyBase: $workbench_secret_key_base
+      ArvadosDocsite: http://$localip:${services[doc]}/
 EOF
 
 /usr/local/lib/arvbox/yml_override.py /var/lib/arvados/cluster_config.yml
index 6f13ee0278f8c67c333b03f338c998c741a8d9a8..9b139500b7fbe8f9f07be3b7538aafe49c768a91 100755 (executable)
@@ -20,10 +20,17 @@ run_bundler --without=development
 bundle exec passenger-config build-native-support
 bundle exec passenger-config install-standalone-runtime
 mkdir -p /usr/src/arvados/apps/workbench/tmp
-RAILS_GROUPS=assets bundle exec rake npm:install
 
 if test "$1" = "--only-deps" ; then
-    exit
+   # Workaround for validation that asserts there's a download URL
+   # configured, which breaks rake if it is missing.
+cat >config/application.yml <<EOF
+$RAILS_ENV:
+  keep_web_url: https://example.com/c=%{uuid_or_pdh}
+EOF
+   RAILS_GROUPS=assets bundle exec rake npm:install
+   rm config/application.yml
+   exit
 fi
 
 set -u
@@ -33,6 +40,9 @@ if ! test -s /var/lib/arvados/workbench_secret_token ; then
 fi
 secret_token=$(cat /var/lib/arvados/workbench_secret_token)
 
+if test -a /usr/src/arvados/apps/workbench/config/arvados_config.rb ; then
+    rm -f config/application.yml
+else
 cat >config/application.yml <<EOF
 $RAILS_ENV:
   secret_token: $secret_token
@@ -47,6 +57,8 @@ $RAILS_ENV:
   workbench2_url: https://$localip:${services[workbench2-ssl]}
 EOF
 
-bundle exec rake assets:precompile
-
 (cd config && /usr/local/lib/arvbox/yml_override.py application.yml)
+fi
+
+RAILS_GROUPS=assets bundle exec rake npm:install
+bundle exec rake assets:precompile
index 6df440a14e37f87f8fcea5cac7c57ca1269915b4..10f1f26f46610dac96ed2b9f1c5cc5e8db0ba528 100644 (file)
@@ -13,21 +13,34 @@ class DygraphsChart(crunchstat_summary.webchart.WebChart):
     def headHTML(self):
         return '<link rel="stylesheet" href="{}">\n'.format(self.CSS)
 
-    def chartdata(self, label, tasks, stat):
+    def chartdata(self, label, tasks, stats):
+        '''For Crunch2, label is the name of container request,
+        tasks is the top level container and
+        stats is index by a tuple of (category, metric).
+        '''
         return {
-            'data': self._collate_data(tasks, stat),
+            'data': self._collate_data(tasks, stats),
             'options': {
+                'legend': 'always',
                 'connectSeparatedPoints': True,
-                'labels': ['elapsed']+[uuid for uuid, _ in tasks.items()],
-                'title': '{}: {} {}'.format(label, stat[0], stat[1]),
+                'labels': ['elapsed'] +  stats[1],
+                'title': '{}: {}'.format(label, stats[0]),
             },
         }
 
-    def _collate_data(self, tasks, stat):
+    def _collate_data(self, tasks, stats):
         data = []
         nulls = []
+        # uuid is category for crunch2
         for uuid, task in tasks.items():
-            for pt in task.series[stat]:
-                data.append([pt[0].total_seconds()] + nulls + [pt[1]])
+            # All stats in a category are assumed to have the same time base and same number of samples
+            category = stats[0]
+            series_names = stats[1]
+            sn0 = series_names[0]
+            series = task.series[(category,sn0)]
+            for i in range(len(series)):
+                pt = series[i]
+                vals = [task.series[(category,stat)][i][1] for stat in series_names[1:]]
+                data.append([pt[0].total_seconds()] + nulls + [pt[1]] + vals)
             nulls.append(None)
         return sorted(data)
index 884f16b4a7db36f64d95bc256938352837f91412..e962ced31404bfe26a7da36d034871941663ef23 100644 (file)
@@ -129,13 +129,14 @@ class Summarizer(object):
                 try:
                     self.label = m.group('job_uuid')
                 except IndexError:
-                    self.label = 'container'
-            if m.group('category').endswith(':'):
+                    self.label = 'label #1'
+            category = m.group('category')
+            if category.endswith(':'):
                 # "stderr crunchstat: notice: ..."
                 continue
-            elif m.group('category') in ('error', 'caught'):
+            elif category in ('error', 'caught'):
                 continue
-            elif m.group('category') in ('read', 'open', 'cgroup', 'CID', 'Running'):
+            elif category in ('read', 'open', 'cgroup', 'CID', 'Running'):
                 # "stderr crunchstat: read /proc/1234/net/dev: ..."
                 # (old logs are less careful with unprefixed error messages)
                 continue
@@ -221,11 +222,11 @@ class Summarizer(object):
                     if group == 'interval' and this_interval_s:
                             stat = stat + '__rate'
                             val = val / this_interval_s
-                            if stat in ['user+sys__rate', 'tx+rx__rate']:
+                            if stat in ['user+sys__rate', 'user__rate', 'sys__rate', 'tx+rx__rate', 'rx__rate', 'tx__rate']:
                                 task.series[category, stat].append(
                                     (timestamp - self.starttime, val))
                     else:
-                        if stat in ['rss']:
+                        if stat in ['rss','used','total']:
                             task.series[category, stat].append(
                                 (timestamp - self.starttime, val))
                         self.task_stats[task_id][category][stat] = val
@@ -315,7 +316,13 @@ class Summarizer(object):
                  (float(self.job_tot['blkio:0:0']['read']) /
                  float(self.job_tot['net:keep0']['rx']))
                  if self.job_tot['net:keep0']['rx'] > 0 else 0,
-                 lambda x: x * 100.0)):
+                 lambda x: x * 100.0),
+               ('Temp disk utilization {}%',
+                 (float(self.job_tot['statfs']['used']) /
+                 float(self.job_tot['statfs']['total']))
+                 if self.job_tot['statfs']['total'] > 0 else 0,
+                 lambda x: x * 100.0),
+                ):
             format_string, val, transform = args
             if val == float('-Inf'):
                 continue
@@ -328,7 +335,9 @@ class Summarizer(object):
         return itertools.chain(
             self._recommend_cpu(),
             self._recommend_ram(),
-            self._recommend_keep_cache())
+            self._recommend_keep_cache(),
+            self._recommend_temp_disk(),
+            )
 
     def _recommend_cpu(self):
         """Recommend asking for 4 cores if max CPU usage was 333%"""
@@ -431,6 +440,21 @@ class Summarizer(object):
                 math.ceil(asked_cache * 2 / self._runtime_constraint_mem_unit()))
 
 
+    def _recommend_temp_disk(self):
+        """Recommend decreasing temp disk if utilization < 50%"""
+        total = float(self.job_tot['statfs']['total'])
+        utilization = (float(self.job_tot['statfs']['used']) / total) if total > 0 else 0.0
+
+        if utilization < 50.8 and total > 0:
+            yield (
+                '#!! {} max temp disk utilization was {:.0f}% of {:.0f} MiB -- '
+                'consider reducing "tmpdirMin" and/or "outdirMin"'
+            ).format(
+                self.label,
+                utilization * 100.0,
+                total / MB)
+
+
     def _format(self, val):
         """Return a string representation of a stat.
 
index cf0c1e67aa1ffdcf7853b2b1271bb2f03b16bae2..31afcf64e906166788bf06b9caa4ed191ead13c9 100644 (file)
@@ -45,10 +45,13 @@ class WebChart(object):
                 'label': s.long_label(),
                 'charts': [
                     self.chartdata(s.label, s.tasks, stat)
-                    for stat in (('cpu', 'user+sys__rate'),
-                                 ('mem', 'rss'),
-                                 ('net:eth0', 'tx+rx__rate'),
-                                 ('net:keep0', 'tx+rx__rate'))],
+                    for stat in (('cpu', ['user+sys__rate', 'user__rate', 'sys__rate']),
+                                 ('mem', ['rss']),
+                                 ('net:eth0', ['tx+rx__rate','rx__rate','tx__rate']),
+                                 ('net:keep0', ['tx+rx__rate','rx__rate','tx__rate']),
+                                 ('statfs', ['used', 'total']),
+                                 )
+                    ],
             }
             for s in self.summarizers]
 
index 0691e4f1ef4ea7e1604a0b7b73787f25b7dd7e58..f77059b82496f5825d9d634847a2b0537efaed72 100644 (file)
@@ -20,3 +20,4 @@ time  elapsed 10      -       10
 # Max network speed in a single interval: 0.00MB/s
 # Keep cache miss rate 0.00%
 # Keep cache utilization 0.00%
+# Temp disk utilization 0.00%
index c64c34c80ec6cd775e81031330070c047265a96d..b17c7005936cee279c69537cb94251845250d9cf 100644 (file)
@@ -23,4 +23,6 @@ time  elapsed 20      -       20
 # Max network speed in a single interval: 0.00MB/s
 # Keep cache miss rate 0.00%
 # Keep cache utilization 0.00%
-#!! container max RSS was 67 MiB -- try reducing runtime_constraints to "ram":1020054732
+# Temp disk utilization 1.21%
+#!! label #1 max RSS was 67 MiB -- try reducing runtime_constraints to "ram":1020054732
+#!! label #1 max temp disk utilization was 1% of 383960 MiB -- consider reducing "tmpdirMin" and/or "outdirMin"
index 3075c24b951020d1444311bc083d269b581219b2..5152e577f5c5a17f3ef57b0c644592f5de14fcb6 100644 (file)
@@ -34,4 +34,6 @@ time  elapsed 20      -       20
 # Max network speed in a single interval: 0.00MB/s
 # Keep cache miss rate 0.00%
 # Keep cache utilization 0.00%
+# Temp disk utilization 1.21%
 #!! container max RSS was 67 MiB -- try reducing runtime_constraints to "ram":1020054732
+#!! container max temp disk utilization was 1% of 383960 MiB -- consider reducing "tmpdirMin" and/or "outdirMin"
index 5e3ad152f7e0e48759312592344cdc936eb95f23..1fb56c7beba7a2e7345bc4580fd2e3d7962d6d1f 100644 (file)
@@ -31,4 +31,5 @@ time  elapsed 80      -       80
 # Max network speed in a single interval: 42.58MB/s
 # Keep cache miss rate 0.00%
 # Keep cache utilization 0.00%
+# Temp disk utilization 0.00%
 #!! 4xphq-8i9sb-jq0ekny1xou3zoh max RSS was 334 MiB -- try reducing runtime_constraints to "min_ram_mb_per_node":972
index e260ca5bdeeed232ee61e094c17fe1ccfad5063f..f567233fb7d6e0cd6fdd3716b1d7dd237a8824f6 100644 (file)
@@ -20,4 +20,5 @@ time  elapsed 2       -       4
 # Max network speed in a single interval: 0.00MB/s
 # Keep cache miss rate 0.00%
 # Keep cache utilization 0.00%
+# Temp disk utilization 0.00%
 #!! 4xphq-8i9sb-zvb2ocfycpomrup max RSS was 1 MiB -- try reducing runtime_constraints to "min_ram_mb_per_node":972
index ffe1072250123f2b05f67ddd62da2bf0881b35a1..ab0febbefa83fcddfe0519c3744f826be50eecc0 100644 (file)
@@ -20,4 +20,5 @@ time  elapsed 2       -       3
 # Max network speed in a single interval: 0.00MB/s
 # Keep cache miss rate 0.00%
 # Keep cache utilization 0.00%
+# Temp disk utilization 0.00%
 #!! 4xphq-8i9sb-v831jm2uq0g2g9x max RSS was 1 MiB -- try reducing runtime_constraints to "min_ram_mb_per_node":972
index 7603ea488c37e4a74f7946d3e108116329b0bad2..0270eaaec06d7fa521e8279022035b6a3bf5bd01 100644 (file)
@@ -102,7 +102,7 @@ class SummarizeContainer(ReportDiff):
                 return UTF8Decode(gzip.open(self.arvmountlog))
         mock_cr().open.side_effect = _open
         args = crunchstat_summary.command.ArgumentParser().parse_args(
-            ['--job', self.fake_request['uuid']])
+            ['--container', self.fake_request['uuid']])
         cmd = crunchstat_summary.command.Command(args)
         cmd.run()
         self.diff_known_report(self.reportfile, cmd)