source 'https://rubygems.org'
-gem 'rails', '~> 3.2.0'
+gem 'rails', '~> 4.1.0'
+gem 'minitest', '>= 5.0.0'
# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'
gem 'oj'
gem 'sass'
+# Note: keeping this out of the "group :assets" section "may" allow us
+# to use Coffescript for UJS responses. It also prevents a
+# warning/problem when running tests: "WARN: tilt autoloading
+# 'coffee_script' in a non thread-safe way; explicit require
+# 'coffee_script' suggested."
+gem 'coffee-rails'
+
# Gems used only for assets and not required
# in production environments by default.
group :assets do
- gem 'sass-rails', '~> 3.2.0'
- gem 'coffee-rails', '~> 3.2.0'
+ gem 'sass-rails'
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
gem 'therubyracer', :platforms => :ruby
gem 'piwik_analytics'
gem 'httpclient'
-gem 'themes_for_rails'
+
+# This fork has Rails 4 compatible routes
+gem 'themes_for_rails', git: 'https://github.com/holtkampw/themes_for_rails', ref: '1fd2d7897d75ae0d6375f4c390df87b8e91ad417'
+
gem "deep_merge", :require => 'deep_merge/rails_compat'
+GIT
+ remote: https://github.com/holtkampw/themes_for_rails
+ revision: 1fd2d7897d75ae0d6375f4c390df87b8e91ad417
+ ref: 1fd2d7897d75ae0d6375f4c390df87b8e91ad417
+ specs:
+ themes_for_rails (0.5.1)
+ rails (>= 3.0.0)
+
GEM
remote: https://rubygems.org/
specs:
RedCloth (4.2.9)
- actionmailer (3.2.15)
- actionpack (= 3.2.15)
+ actionmailer (4.1.1)
+ actionpack (= 4.1.1)
+ actionview (= 4.1.1)
mail (~> 2.5.4)
- actionpack (3.2.15)
- activemodel (= 3.2.15)
- activesupport (= 3.2.15)
- builder (~> 3.0.0)
+ actionpack (4.1.1)
+ actionview (= 4.1.1)
+ activesupport (= 4.1.1)
+ rack (~> 1.5.2)
+ rack-test (~> 0.6.2)
+ actionview (4.1.1)
+ activesupport (= 4.1.1)
+ builder (~> 3.1)
erubis (~> 2.7.0)
- journey (~> 1.0.4)
- rack (~> 1.4.5)
- rack-cache (~> 1.2)
- rack-test (~> 0.6.1)
- sprockets (~> 2.2.1)
- activemodel (3.2.15)
- activesupport (= 3.2.15)
- builder (~> 3.0.0)
- activerecord (3.2.15)
- activemodel (= 3.2.15)
- activesupport (= 3.2.15)
- arel (~> 3.0.2)
- tzinfo (~> 0.3.29)
- activeresource (3.2.15)
- activemodel (= 3.2.15)
- activesupport (= 3.2.15)
- activesupport (3.2.15)
- i18n (~> 0.6, >= 0.6.4)
- multi_json (~> 1.0)
+ activemodel (4.1.1)
+ activesupport (= 4.1.1)
+ builder (~> 3.1)
+ activerecord (4.1.1)
+ activemodel (= 4.1.1)
+ activesupport (= 4.1.1)
+ arel (~> 5.0.0)
+ activesupport (4.1.1)
+ i18n (~> 0.6, >= 0.6.9)
+ json (~> 1.7, >= 1.7.7)
+ minitest (~> 5.1)
+ thread_safe (~> 0.1)
+ tzinfo (~> 1.1)
andand (1.3.3)
- arel (3.0.2)
+ arel (5.0.1.20140414130214)
bootstrap-sass (3.1.0.1)
sass (~> 3.2)
bootstrap-x-editable-rails (1.5.1.1)
railties (>= 3.0)
- builder (3.0.4)
+ builder (3.2.2)
capistrano (2.15.5)
highline
net-scp (>= 1.0.0)
childprocess (0.5.1)
ffi (~> 1.0, >= 1.0.11)
cliver (0.3.2)
- coffee-rails (3.2.2)
+ coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
- railties (~> 3.2.0)
+ railties (>= 4.0.0, < 5.0)
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.6.3)
+ coffee-script-source (1.7.0)
commonjs (0.2.7)
daemon_controller (1.1.7)
deep_merge (1.0.1)
highline (1.6.20)
hike (1.2.3)
httpclient (2.3.4.1)
- i18n (0.6.5)
- journey (1.0.4)
+ i18n (0.6.9)
jquery-rails (3.0.4)
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mime-types (1.25)
+ mime-types (1.25.1)
mini_portile (0.5.2)
- multi_json (1.8.2)
+ minitest (5.3.3)
+ multi_json (1.10.0)
net-scp (1.1.2)
net-ssh (>= 2.6.5)
net-sftp (2.1.2)
cliver (~> 0.3.1)
multi_json (~> 1.0)
websocket-driver (>= 0.2.0)
- polyglot (0.3.3)
- rack (1.4.5)
- rack-cache (1.2)
- rack (>= 0.4)
- rack-ssl (1.3.3)
- rack
+ polyglot (0.3.4)
+ rack (1.5.2)
rack-test (0.6.2)
rack (>= 1.0)
- rails (3.2.15)
- actionmailer (= 3.2.15)
- actionpack (= 3.2.15)
- activerecord (= 3.2.15)
- activeresource (= 3.2.15)
- activesupport (= 3.2.15)
- bundler (~> 1.0)
- railties (= 3.2.15)
- railties (3.2.15)
- actionpack (= 3.2.15)
- activesupport (= 3.2.15)
- rack-ssl (~> 1.3.2)
+ rails (4.1.1)
+ actionmailer (= 4.1.1)
+ actionpack (= 4.1.1)
+ actionview (= 4.1.1)
+ activemodel (= 4.1.1)
+ activerecord (= 4.1.1)
+ activesupport (= 4.1.1)
+ bundler (>= 1.3.0, < 2.0)
+ railties (= 4.1.1)
+ sprockets-rails (~> 2.0)
+ railties (4.1.1)
+ actionpack (= 4.1.1)
+ activesupport (= 4.1.1)
rake (>= 0.8.7)
- rdoc (~> 3.4)
- thor (>= 0.14.6, < 2.0)
- rake (10.1.0)
- rdoc (3.12.2)
- json (~> 1.4)
+ thor (>= 0.18.1, < 2.0)
+ rake (10.3.1)
ref (1.0.5)
rubyzip (1.1.0)
rvm-capistrano (1.5.1)
capistrano (~> 2.15.4)
sass (3.2.12)
- sass-rails (3.2.6)
- railties (~> 3.2.0)
- sass (>= 3.1.10)
- tilt (~> 1.3)
+ sass-rails (4.0.3)
+ railties (>= 4.0.0, < 5.0)
+ sass (~> 3.2.0)
+ sprockets (~> 2.8, <= 2.11.0)
+ sprockets-rails (~> 2.0)
selenium-webdriver (2.40.0)
childprocess (>= 0.5.0)
multi_json (~> 1.0)
simplecov-html (0.7.1)
simplecov-rcov (0.2.3)
simplecov (>= 0.4.1)
- sprockets (2.2.2)
+ sprockets (2.11.0)
hike (~> 1.2)
multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
+ sprockets-rails (2.1.3)
+ actionpack (>= 3.0)
+ activesupport (>= 3.0)
+ sprockets (~> 2.8)
sqlite3 (1.3.8)
- themes_for_rails (0.5.1)
- rails (>= 3.0.0)
therubyracer (0.12.0)
libv8 (~> 3.16.14.0)
ref
- thor (0.18.1)
+ thor (0.19.1)
+ thread_safe (0.3.3)
tilt (1.4.1)
treetop (1.4.15)
polyglot
polyglot (>= 0.3.1)
- tzinfo (0.3.38)
+ tzinfo (1.1.0)
+ thread_safe (~> 0.1)
uglifier (2.3.1)
execjs (>= 0.3.0)
json (>= 1.8.0)
bootstrap-sass (~> 3.1.0)
bootstrap-x-editable-rails
capybara
- coffee-rails (~> 3.2.0)
+ coffee-rails
deep_merge
headless
httpclient
jquery-rails
less
less-rails
+ minitest (>= 5.0.0)
multi_json
oj
passenger
piwik_analytics
poltergeist
- rails (~> 3.2.0)
+ rails (~> 4.1.0)
rvm-capistrano
sass
- sass-rails (~> 3.2.0)
+ sass-rails
selenium-webdriver
simplecov (~> 0.7.1)
simplecov-rcov
sqlite3
- themes_for_rails
+ themes_for_rails!
therubyracer
uglifier (>= 1.0.3)
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
-
cache_age_in_days = (milliseconds_age) ->
ONE_DAY = 1000 * 60 * 60 * 24
milliseconds_age / ONE_DAY
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
-
(function() {
var run_pipeline_button_state = function() {
var a = $('a.editable.required.editable-empty');
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
+++ /dev/null
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
env = Hash[ENV].
merge({
'ARVADOS_API_HOST' =>
- $arvados_api_client.arvados_v1_base.
+ arvados_api_client.arvados_v1_base.
sub(/\/arvados\/v1/, '').
sub(/^https?:\/\//, ''),
'ARVADOS_API_TOKEN' => Thread.current[:arvados_api_token],
class ApplicationController < ActionController::Base
+ include ArvadosApiClientHelper
+
respond_to :html, :json, :js
protect_from_forgery
respond_to do |f|
f.html {
if request.method == 'GET'
- redirect_to $arvados_api_client.arvados_login_url(return_to: request.url)
+ redirect_to arvados_api_client.arvados_login_url(return_to: request.url)
else
flash[:error] = "Either you are not logged in, or your session has timed out. I can't automatically log you in and re-attempt this request."
redirect_to :back
env = Hash[ENV].
merge({
'ARVADOS_API_HOST' =>
- $arvados_api_client.arvados_v1_base.
+ arvados_api_client.arvados_v1_base.
sub(/\/arvados\/v1/, '').
sub(/^https?:\/\//, ''),
'ARVADOS_API_TOKEN' =>
skip_before_filter :find_object_by_uuid, :only => [:destroy, :index]
def destroy
session.clear
- redirect_to $arvados_api_client.arvados_logout_url(return_to: root_url)
+ redirect_to arvados_api_client.arvados_logout_url(return_to: root_url)
end
def index
redirect_to root_url if session[:arvados_api_token]
end
def sudo
- resp = $arvados_api_client.api(ApiClientAuthorization, '', {
- api_client_authorization: {
- owner_uuid: @object.uuid
- }
- })
+ resp = arvados_api_client.api(ApiClientAuthorization, '', {
+ api_client_authorization: {
+ owner_uuid: @object.uuid
+ }
+ })
redirect_to root_url(api_token: resp[:api_token])
end
--- /dev/null
+module ArvadosApiClientHelper
+ def arvados_api_client
+ ArvadosApiClient.new_or_current
+ end
+end
+
+# For the benefit of themes that still expect $arvados_api_client to work:
+class ArvadosClientProxyHack
+ def method_missing *args
+ ArvadosApiClient.new_or_current.send *args
+ end
+end
+$arvados_api_client = ArvadosClientProxyHack.new
class InvalidApiResponseException < StandardError
end
- @@client_mtx = Mutex.new
- @@api_client = nil
@@profiling_enabled = Rails.configuration.profiling_enabled
+ @@discovery = nil
+
+ # An API client object suitable for handling API requests on behalf
+ # of the current thread.
+ def self.new_or_current
+ Thread.current[:arvados_api_client] ||= new
+ end
+
+ def initialize *args
+ @api_client = nil
+ @client_mtx = Mutex.new
+ end
def api(resources_kind, action, data=nil)
profile_checkpoint
- @@client_mtx.synchronize do
- if not @@api_client
- @@api_client = HTTPClient.new
+ if not @api_client
+ @client_mtx.synchronize do
+ @api_client = HTTPClient.new
if Rails.configuration.arvados_insecure_https
- @@api_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
+ @api_client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
else
# Use system CA certificates
- @@api_client.ssl_config.add_trust_ca('/etc/ssl/certs')
+ @api_client.ssl_config.add_trust_ca('/etc/ssl/certs')
end
end
end
header = {"Accept" => "application/json"}
profile_checkpoint { "Prepare request #{url} #{query[:uuid]} #{query[:where]} #{query[:filters]}" }
- msg = @@api_client.post(url,
- query,
- header: header)
+ msg = @client_mtx.synchronize do
+ @api_client.post(url,
+ query,
+ header: header)
+ end
profile_checkpoint 'API transaction'
if msg.status_code == 401
end
def discovery
- @discovery ||= api '../../discovery/v1/apis/arvados/v1/rest', ''
+ @@discovery ||= api '../../discovery/v1/apis/arvados/v1/rest', ''
end
def kind_class(kind)
self.abstract_class = true
attr_accessor :attribute_sortkey
+ def self.arvados_api_client
+ ArvadosApiClient.new_or_current
+ end
+
+ def arvados_api_client
+ ArvadosApiClient.new_or_current
+ end
+
def self.uuid_infix_object_kind
@@uuid_infix_object_kind ||=
begin
infix_kind = {}
- $arvados_api_client.discovery[:schemas].each do |name, schema|
+ arvados_api_client.discovery[:schemas].each do |name, schema|
if schema[:uuidPrefix]
infix_kind[schema[:uuidPrefix]] =
'arvados#' + name.to_s.camelcase(:lower)
end
end
- def initialize(*args)
- super(*args)
+ def initialize raw_params={}
+ super self.class.permit_attribute_params(raw_params)
@attribute_sortkey ||= {
'id' => nil,
'name' => '000',
return @columns unless @columns.nil?
@columns = []
@attribute_info ||= {}
- schema = $arvados_api_client.discovery[:schemas][self.to_s.to_sym]
+ schema = arvados_api_client.discovery[:schemas][self.to_s.to_sym]
return @columns if schema.nil?
schema[:properties].each do |k, coldef|
case k
@columns << column(k, :text)
serialize k, coldef[:type].constantize
end
- attr_accessible k
@attribute_info[k] = coldef
end
end
# request} unless {cache: false} is given via opts.
cache_key = "request_#{Thread.current.object_id}_#{self.to_s}_#{uuid}"
if opts[:cache] == false
- Rails.cache.write cache_key, $arvados_api_client.api(self, '/' + uuid)
+ Rails.cache.write cache_key, arvados_api_client.api(self, '/' + uuid)
end
hash = Rails.cache.fetch cache_key do
- $arvados_api_client.api(self, '/' + uuid)
+ arvados_api_client.api(self, '/' + uuid)
end
new.private_reload(hash)
end
ArvadosResourceList.new(self).all(*args)
end
+ def self.permit_attribute_params raw_params
+ # strong_parameters does not provide security in Workbench: anyone
+ # who can get this far can just as well do a call directly to our
+ # database (Arvados) with the same credentials we use.
+ #
+ # The following permit! is necessary even with
+ # "ActionController::Parameters.permit_all_parameters = true",
+ # because permit_all does not permit nested attributes.
+ ActionController::Parameters.new(raw_params).permit!
+ end
+
+ def self.create raw_params={}
+ super(permit_attribute_params(raw_params))
+ end
+
+ def update_attributes raw_params={}
+ super(self.class.permit_attribute_params(raw_params))
+ end
+
def save
obdata = {}
self.class.columns.each do |col|
if etag
postdata['_method'] = 'PUT'
obdata.delete :uuid
- resp = $arvados_api_client.api(self.class, '/' + uuid, postdata)
+ resp = arvados_api_client.api(self.class, '/' + uuid, postdata)
else
- resp = $arvados_api_client.api(self.class, '', postdata)
+ resp = arvados_api_client.api(self.class, '', postdata)
end
return false if !resp[:etag] || !resp[:uuid]
def destroy
if etag || uuid
postdata = { '_method' => 'DELETE' }
- resp = $arvados_api_client.api(self.class, '/' + uuid, postdata)
+ resp = arvados_api_client.api(self.class, '/' + uuid, postdata)
resp[:etag] && resp[:uuid] && resp
else
true
ok
end
end
- @links = $arvados_api_client.api Link, '', { _method: 'GET', where: o, eager: true }
- @links = $arvados_api_client.unpack_api_response(@links)
+ @links = arvados_api_client.api Link, '', { _method: 'GET', where: o, eager: true }
+ @links = arvados_api_client.unpack_api_response(@links)
end
def all_links
return @all_links if @all_links
- res = $arvados_api_client.api Link, '', {
+ res = arvados_api_client.api Link, '', {
_method: 'GET',
where: {
tail_kind: self.kind,
},
eager: true
}
- @all_links = $arvados_api_client.unpack_api_response(res)
+ @all_links = arvados_api_client.unpack_api_response(res)
end
def reload
if uuid_or_hash.is_a? Hash
hash = uuid_or_hash
else
- hash = $arvados_api_client.api(self.class, '/' + uuid_or_hash)
+ hash = arvados_api_client.api(self.class, '/' + uuid_or_hash)
end
hash.each do |k,v|
if self.respond_to?(k.to_s + '=')
end
resource_class = nil
uuid.match /^[0-9a-z]{5}-([0-9a-z]{5})-[0-9a-z]{15}$/ do |re|
- resource_class ||= $arvados_api_client.
+ resource_class ||= arvados_api_client.
kind_class(self.uuid_infix_object_kind[re[1]])
end
if opts[:referring_object] and
opts[:referring_attr] and
opts[:referring_attr].match /_uuid$/
- resource_class ||= $arvados_api_client.
+ resource_class ||= arvados_api_client.
kind_class(opts[:referring_object].
attributes[opts[:referring_attr].
sub(/_uuid$/, '_kind')])
class ArvadosResourceList
+ include ArvadosApiClientHelper
include Enumerable
def initialize resource_class=nil
end
cond.keys.select { |x| x.match /_kind$/ }.each do |kind_key|
if cond[kind_key].is_a? Class
- cond = cond.merge({ kind_key => 'arvados#' + $arvados_api_client.class_kind(cond[kind_key]) })
+ cond = cond.merge({ kind_key => 'arvados#' + arvados_api_client.class_kind(cond[kind_key]) })
end
end
api_params = {
api_params[:offset] = @offset if @offset
api_params[:order] = @orderby_spec if @orderby_spec
api_params[:filters] = @filters if @filters
- res = $arvados_api_client.api @resource_class, '', api_params
- @results = $arvados_api_client.unpack_api_response res
+ res = arvados_api_client.api @resource_class, '', api_params
+ @results = arvados_api_client.unpack_api_response res
self
end
end
def provenance
- $arvados_api_client.api "collections/#{self.uuid}/", "provenance"
+ arvados_api_client.api "collections/#{self.uuid}/", "provenance"
end
def used_by
- $arvados_api_client.api "collections/#{self.uuid}/", "used_by"
+ arvados_api_client.api "collections/#{self.uuid}/", "used_by"
end
end
class Group < ArvadosBase
def contents params={}
- res = $arvados_api_client.api self.class, "/#{self.uuid}/contents", {
+ res = arvados_api_client.api self.class, "/#{self.uuid}/contents", {
_method: 'GET'
}.merge(params)
ret = ArvadosResourceList.new
- ret.results = $arvados_api_client.unpack_api_response(res)
+ ret.results = arvados_api_client.unpack_api_response(res)
ret
end
end
def self.current
- res = $arvados_api_client.api self, '/current'
- $arvados_api_client.unpack_api_response(res)
+ res = arvados_api_client.api self, '/current'
+ arvados_api_client.unpack_api_response(res)
end
def self.system
- $arvados_system_user ||= begin
- res = $arvados_api_client.api self, '/system'
- $arvados_api_client.unpack_api_response(res)
- end
+ @@arvados_system_user ||= begin
+ res = arvados_api_client.api self, '/system'
+ arvados_api_client.unpack_api_response(res)
+ end
end
def full_name
end
def activate
- self.private_reload($arvados_api_client.api(self.class,
- "/#{self.uuid}/activate",
- {}))
+ self.private_reload(arvados_api_client.api(self.class,
+ "/#{self.uuid}/activate",
+ {}))
end
def attributes_for_display
end
def unsetup
- self.private_reload($arvados_api_client.api(self.class,
- "/#{self.uuid}/unsetup",
- {}))
+ self.private_reload(arvados_api_client.api(self.class,
+ "/#{self.uuid}/unsetup",
+ {}))
end
def self.setup params
- $arvados_api_client.api(self, "/setup", params)
+ arvados_api_client.api(self, "/setup", params)
end
end
class UserAgreement < ArvadosBase
def self.signatures
- res = $arvados_api_client.api self, '/signatures'
- $arvados_api_client.unpack_api_response(res)
+ res = arvados_api_client.api self, '/signatures'
+ arvados_api_client.unpack_api_response(res)
end
def self.sign(params)
- res = $arvados_api_client.api self, '/sign', params
- $arvados_api_client.unpack_api_response(res)
+ res = arvados_api_client.api self, '/sign', params
+ arvados_api_client.unpack_api_response(res)
end
end
</ul>
</li>
<% else %>
- <li><a href="<%= $arvados_api_client.arvados_login_url(return_to: root_url) %>">Log in</a></li>
+ <li><a href="<%= arvados_api_client.arvados_login_url(return_to: root_url) %>">Log in</a></li>
<% end %>
</ul>
</div><!-- /.navbar-collapse -->
<td>
<% if current_user and (current_user.is_admin or current_user.uuid == link.owner_uuid) %>
- <%= link_to raw('<i class="glyphicon glyphicon-trash"></i>'), { action: 'destroy', id: link.uuid }, { confirm: 'Delete this link?', method: 'delete' } %>
+ <%= link_to raw('<i class="glyphicon glyphicon-trash"></i>'), { action: 'destroy', id: link.uuid }, data: {confirm: 'Delete this link?', method: 'delete'} %>
<% end %>
</td>
<p>As an admin, you can deactivate and reset this user. This will remove all repository/VM permissions for the user. If you "setup" the user again, the user will have to sign the user agreement again.</p>
<blockquote>
-<%= button_to "Deactivate #{@object.full_name}", unsetup_user_url(id: @object.uuid), class: 'btn btn-primary', confirm: "Are you sure you want to deactivate #{@object.full_name}?"%>
+<%= button_to "Deactivate #{@object.full_name}", unsetup_user_url(id: @object.uuid), class: 'btn btn-primary', data: {confirm: "Are you sure you want to deactivate #{@object.full_name}?"} %>
</blockquote>
<% content_for :footer_html do %>
beyond that.
</p>
<p>
- <a class="pull-right btn btn-primary" href="<%= $arvados_api_client.arvados_login_url(return_to: request.url) %>">
+ <a class="pull-right btn btn-primary" href="<%= arvados_api_client.arvados_login_url(return_to: request.url) %>">
Click here to log in to <%= Rails.configuration.site_name %> with a Google account</a>
</p>
</div>
$("#PutStuffHere").append(content + "<br>");
};
-var dispatcher = new WebSocket('<%= $arvados_api_client.discovery[:websocketUrl] %>?api_token=<%= Thread.current[:arvados_api_token] %>');
+var dispatcher = new WebSocket('<%= arvados_api_client.discovery[:websocketUrl] %>?api_token=<%= Thread.current[:arvados_api_token] %>');
dispatcher.onmessage = function(event) {
//putStuffThere(JSON.parse(event.data));
putStuffThere(event.data);
development:
cache_classes: false
- whiny_nils: true
+ eager_load: true
consider_all_requests_local: true
action_controller.perform_caching: false
action_mailer.raise_delivery_errors: false
active_support.deprecation: :log
action_dispatch.best_standards_support: :builtin
- active_record.mass_assignment_sanitizer: :strict
- active_record.auto_explain_threshold_in_seconds: 0.5
- assets.compress: false
assets.debug: true
profiling_enabled: true
site_name: Arvados Workbench (dev)
production:
force_ssl: true
cache_classes: true
+ eager_load: true
consider_all_requests_local: false
action_controller.perform_caching: true
serve_static_assets: false
- assets.compress: true
assets.compile: false
assets.digest: true
i18n.fallbacks: true
test:
cache_classes: true
+ eager_load: false
serve_static_assets: true
static_cache_control: public, max-age=3600
- whiny_nils: true
consider_all_requests_local: true
action_controller.perform_caching: false
action_dispatch.show_exceptions: false
action_controller.allow_forgery_protection: false
action_mailer.delivery_method: :test
- active_record.mass_assignment_sanitizer: :strict
active_support.deprecation: :stderr
profiling_enabled: false
secret_token: <%= rand(2**256).to_s(36) %>
+ secret_key_base: <%= rand(2**256).to_s(36) %>
# When you run the Workbench's integration tests, it starts the API
# server as a dependency. These settings should match the API
site_name: Workbench:test
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_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
require 'rails/all'
-if defined?(Bundler)
- # If you precompile assets before deploying to production, use this line
- Bundler.require(*Rails.groups(:assets => %w(development test)))
- # If you want your assets lazily compiled in production, use this line
- # Bundler.require(:default, :assets, Rails.env)
-end
+Bundler.require(:default, Rails.env)
module ArvadosWorkbench
class Application < Rails::Application
# like if you have constraints or database-specific column types
# config.active_record.schema_format = :sql
- # Enforce whitelist mode for mass assignment.
- # This will create an empty whitelist of attributes available for mass-assignment for all models
- # in your app. As such, your models will need to explicitly whitelist or blacklist accessible
- # parameters by using an attr_accessible or attr_protected declaration.
- config.active_record.whitelist_attributes = true
-
# Enable the asset pipeline
config.assets.enabled = true
config.assets.version = '1.0'
end
end
+
+require File.expand_path('../load_config', __FILE__)
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
- # Log error messages when you accidentally call methods on nil.
- config.whiny_nils = true
-
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Only use best-standards-support built into browsers
config.action_dispatch.best_standards_support = :builtin
- # Raise exception on mass assignment protection for Active Record models
- config.active_record.mass_assignment_sanitizer = :strict
-
- # Log the query plan for queries taking more than this (works
- # with SQLite, MySQL, and PostgreSQL)
- config.active_record.auto_explain_threshold_in_seconds = 0.5
-
# Do not compress assets
- config.assets.compress = false
+ config.assets.js_compressor = false
# Expands the lines which load the assets
config.assets.debug = true
config.serve_static_assets = false
# Compress JavaScripts and CSS
- config.assets.compress = true
+ config.assets.js_compressor = :yui
# Don't fallback to assets pipeline if a precompiled asset is missed
config.assets.compile = false
# Send deprecation notices to registered listeners
config.active_support.deprecation = :notify
- # Log the query plan for queries taking more than this (works
- # with SQLite, MySQL, and PostgreSQL)
- # config.active_record.auto_explain_threshold_in_seconds = 0.5
-
# Log timing data for API transactions
config.profiling_enabled = false
config.serve_static_assets = true
config.static_cache_control = "public, max-age=3600"
- # Log error messages when you accidentally call methods on nil
- config.whiny_nils = true
-
# Show full error reports and disable caching
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
- # Raise exception on mass assignment protection for Active Record models
- config.active_record.mass_assignment_sanitizer = :strict
-
# Print deprecation notices to the stderr
config.active_support.deprecation = :stderr
+++ /dev/null
-# The client object must be instantiated _after_ zza_load_config.rb
-# runs, because it relies on configuration settings.
-#
-if not $application_config
- raise "Fatal: Config must be loaded before instantiating ArvadosApiClient."
-end
-
-$arvados_api_client = ArvadosApiClient.new
resources :authorized_keys
resources :job_tasks
resources :jobs
- match '/logout' => 'sessions#destroy'
- match '/logged_out' => 'sessions#index'
+ match '/logout' => 'sessions#destroy', via: [:get, :post]
+ get '/logged_out' => 'sessions#index'
resources :users do
get 'home', :on => :member
get 'welcome', :on => :collection
get 'compare', on: :collection
end
resources :links
- match '/collections/graph' => 'collections#graph'
+ get '/collections/graph' => 'collections#graph'
resources :collections do
post 'set_persistent', on: :member
end
# Send unroutable requests to an arbitrary controller
# (ends up at ApplicationController#render_not_found)
- match '*a', :to => 'links#render_not_found'
+ match '*a', to: 'links#render_not_found', via: [:get, :post]
end
fill_in "email", :with => "foo@example.com"
fill_in "repo_name", :with => "test_repo"
click_button "Submit"
+ wait_for_ajax
end
visit '/users'
assert has_text? 'Virtual Machine'
fill_in "repo_name", :with => "test_repo"
click_button "Submit"
+ wait_for_ajax
end
- sleep(1)
assert page.has_text? 'modified_by_client_uuid'
click_link 'Metadata'
fill_in "repo_name", :with => "second_test_repo"
select("testvm.shell", :from => 'vm_uuid')
click_button "Submit"
+ wait_for_ajax
end
- sleep(0.1)
assert page.has_text? 'modified_by_client_uuid'
click_link 'Metadata'
fill_in "repo_name", :with => "second_test_repo"
select("testvm.shell", :from => 'vm_uuid')
click_button "Submit"
+ wait_for_ajax
end
- sleep(0.1)
assert page.has_text? 'modified_by_client_uuid'
click_link 'Metadata'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
-$ARV_API_SERVER_DIR = File.expand_path('../../../../services/api', __FILE__)
-SERVER_PID_PATH = 'tmp/pids/server.pid'
-
class ActiveSupport::TestCase
# Setup all fixtures in test/fixtures/*.(yml|csv) for all tests in
# alphabetical order.
# Returns the data structure from the named API server test fixture.
@@api_fixtures[name] ||= \
begin
- path = File.join($ARV_API_SERVER_DIR, 'test', 'fixtures', "#{name}.yml")
+ path = File.join(ApiServerForTests::ARV_API_SERVER_DIR,
+ 'test', 'fixtures', "#{name}.yml")
YAML.load(IO.read(path))
end
end
end
end
-class ApiServerBackedTestRunner < MiniTest::Unit
- def _system(*cmd)
+class ApiServerForTests
+ ARV_API_SERVER_DIR = File.expand_path('../../../../services/api', __FILE__)
+ SERVER_PID_PATH = File.expand_path('tmp/pids/wbtest-server.pid', ARV_API_SERVER_DIR)
+ @main_process_pid = $$
+
+ def self._system(*cmd)
+ $stderr.puts "_system #{cmd.inspect}"
Bundler.with_clean_env do
if not system({'RAILS_ENV' => 'test'}, *cmd)
raise RuntimeError, "#{cmd[0]} returned exit code #{$?.exitstatus}"
end
end
- def _run(args=[])
+ def self.make_ssl_cert
+ unless File.exists? './self-signed.key'
+ _system('openssl', 'req', '-new', '-x509', '-nodes',
+ '-out', './self-signed.pem',
+ '-keyout', './self-signed.key',
+ '-days', '3650',
+ '-subj', '/CN=localhost')
+ end
+ end
+
+ def self.kill_server
+ if (pid = find_server_pid)
+ $stderr.puts "Sending TERM to API server, pid #{pid}"
+ Process.kill 'TERM', pid
+ end
+ end
+
+ def self.find_server_pid
+ pid = nil
+ begin
+ pid = IO.read(SERVER_PID_PATH).to_i
+ $stderr.puts "API server is running, pid #{pid.inspect}"
+ rescue Errno::ENOENT
+ end
+ return pid
+ end
+
+ def self.run(args=[])
+ ::MiniTest.after_run do
+ self.kill_server
+ end
+
+ # Kill server left over from previous test run
+ self.kill_server
+
Capybara.javascript_driver = :poltergeist
- server_pid = Dir.chdir($ARV_API_SERVER_DIR) do |apidir|
+ Dir.chdir(ARV_API_SERVER_DIR) do |apidir|
ENV["NO_COVERAGE_TEST"] = "1"
+ make_ssl_cert
_system('bundle', 'exec', 'rake', 'db:test:load')
_system('bundle', 'exec', 'rake', 'db:fixtures:load')
- _system('bundle', 'exec', 'rails', 'server', '-d')
+ _system('bundle', 'exec', 'passenger', 'start', '-d', '-p3001',
+ '--pid-file', SERVER_PID_PATH,
+ '--ssl',
+ '--ssl-certificate', 'self-signed.pem',
+ '--ssl-certificate-key', 'self-signed.key')
timeout = Time.now.tv_sec + 10
good_pid = false
while (not good_pid) and (Time.now.tv_sec < timeout)
sleep 0.2
- begin
- server_pid = IO.read(SERVER_PID_PATH).to_i
- good_pid = (server_pid > 0) and (Process.kill(0, server_pid) rescue false)
- rescue Errno::ENOENT
- good_pid = false
- end
+ server_pid = find_server_pid
+ good_pid = (server_pid and
+ (server_pid > 0) and
+ (Process.kill(0, server_pid) rescue false))
end
if not good_pid
raise RuntimeError, "could not find API server Rails pid"
end
- server_pid
- end
- begin
- super(args)
- ensure
- Process.kill('TERM', server_pid)
end
end
end
-MiniTest::Unit.runner = ApiServerBackedTestRunner.new
+ApiServerForTests.run
~/arvados/apps/workbench$ <span class="userinput">bundle install --path=vendor/bundle</span>
</code></pre></notextile>
+The @bundle install@ command might produce a warning about the themes_for_rails gem. This is OK:
+
+<notextile>
+<pre><code>themes_for_rails at /home/<b>you</b>/.rvm/gems/ruby-2.1.1/bundler/gems/themes_for_rails-1fd2d7897d75 did not have a valid gemspec.
+This prevents bundler from installing bins or native extensions, but that may not affect its functionality.
+The validation message from Rubygems was:
+ duplicate dependency on rails (= 3.0.11, development), (>= 3.0.0) use:
+ add_runtime_dependency 'rails', '= 3.0.11', '>= 3.0.0'
+Using themes_for_rails (0.5.1) from https://github.com/holtkampw/themes_for_rails (at 1fd2d78)
+</code></pre></notextile>
+
h2. Configure the Workbench application
This application needs a secret token. Generate a new secret: