# 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])
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
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
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
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,
# 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
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
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 " \
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] + '/'
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
}
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
}
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
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
}
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 }
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
}
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
}
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
}
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
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
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
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
}
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
}
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)
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
# 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
# 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
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
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
.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
# 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] ||
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={})
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
# 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
'!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
<%= 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
<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 %>
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}") %>
<%
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]
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
<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="">
<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> > <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> > <a href="<%= Rails.configuration.Workbench.ArvadosPublicDataDocURL %>">Public Pipelines and Datasets</a>
</li><li>
Pro-tip: A Pipeline contains Jobs which contain Tasks
</li><li>
<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
<% 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();
<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">
<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] %>
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%>" />
<%= 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>
<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 %>
<% 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'}) %>
</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
</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'
%>
<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>
<% 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 %>
<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>
</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">
<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 %>
<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")%>
<%= 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>
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>
-
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>
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
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
</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">
<p>
See also:
<%= link_to raw('Arvados Docs → User Guide → 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 → User Guide → 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>
<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>
<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>
</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
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">
<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>
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" %>,
</p>
<p style="padding-bottom: 1em">
<%= link_to raw('Contact us ✉'),
- 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>
<div id="manage_virtual_machines" class="panel-body">
<p>
For more information see <%= link_to raw('Arvados Docs → User Guide → 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>
<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>
<% 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 %>
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>
</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>
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>
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>
<p>
See also:
<%= link_to raw('Arvados Docs → User Guide → 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>
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 {
</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 %>
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
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
- 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
# 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
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.
config.assets.paths << Rails.root.join('node_modules')
end
end
-
-require File.expand_path('../load_config', __FILE__)
--- /dev/null
+# 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
+++ /dev/null
-# 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
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
--- /dev/null
+# 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
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
--- /dev/null
+# 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
+++ /dev/null
-# 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
+++ /dev/null
-# 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
['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'
['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
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"
].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"
# 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
].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
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))
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
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|
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)
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)
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: {
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
[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)
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)
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
: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)
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
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
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
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)
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
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
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']}"
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
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
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'
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
end
[
- [false, false],
+ ["", false],
['http://wb2.example.org//', false],
['ftp://wb2.example.org', false],
['wb2.example.org', false],
['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
['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)
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
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.'
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]
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]
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'
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']
need_javascript
end
+ teardown do
+ Rails.configuration.testing_override_login_url = false
+ end
+
def start_sso_stub token
port = available_port('sso_stub')
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"
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"
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"
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"
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"
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"
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",
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"))
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')
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
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
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')
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
[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 ('/')
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'
['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
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
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
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
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
# 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
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
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
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
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
[
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
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)
/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
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
/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"]
/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"]
/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"]
/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"]
/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"]
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
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
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
-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
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"
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
)
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" \
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
}
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
"-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,
})
)
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
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
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
$ 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@.
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.
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
|@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|
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.
{% 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:
<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
# 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;
}
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:
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@—never edit @config/application.default.yml@.
-
-h3. secret_token
+h3. Workbench.SecretKeyBase
This application needs a secret token. Generate a new secret:
</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
#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;
}
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 / {
@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@.
"fmt"
"io"
"os"
- "os/user"
"git.curoverse.com/arvados.git/lib/cloud"
"git.curoverse.com/arvados.git/lib/config"
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")
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 {
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) {
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
+}
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: "-"
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: {}
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
# 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.
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).
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: ""
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: {}
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: ""
// 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 {
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: "-"
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: {}
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
# 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.
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).
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: ""
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: {}
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: ""
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)
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)
ManagedProperties map[string]interface{}
PreserveVersionIfIdle Duration
TrashSweepInterval Duration
+ TrustAllContent bool
}
Git struct {
Repositories string
Mail struct {
MailchimpAPIKey string
MailchimpListID string
- SendUserSetupNotificationEmail string
+ SendUserSetupNotificationEmail bool
IssueReporterEmailFrom string
IssueReporterEmailTo string
SupportEmailAddress string
Insecure bool
}
Users struct {
+ AnonymousUserToken string
AdminNotifierEmailFrom string
AutoAdminFirstUser bool
AutoAdminUserWithEmail string
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
FormFieldTitle string
FormFieldDescription string
Required bool
+ Position int
+ Options map[string]struct{}
}
UserProfileFormMessage string
VocabularyURL string
# delete application.yml and database.yml.
require 'config_loader'
+require 'open3'
begin
# If secret_token.rb exists here, we need to load it first.
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
+++ /dev/null
-../../../lib/config/config.default.yml
\ No newline at end of file
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
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
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)
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
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
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
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
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:
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
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
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
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
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)
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
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
(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
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%"""
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.
'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]
# 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%
# 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"
# 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"
# 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
# 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
# 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
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)