Skip to content

Commit

Permalink
Several fixes all bundled together.
Browse files Browse the repository at this point in the history
1- The controls channel for Bourreau has a new 'StopYourself'
   command, which is much more efficient than the old way
   of stopping the rails app using an external script.
   Fixes #55 .
2- The 'ibc' utility provides access to it with the 'J' command
3- Tooltips in the interface could never be positioned
   at offset_x set to 0 because 0 is falsy in javascript. Fixed.
4- We no longer ever keep a backup of database.yml on remote sites.
5- Userfiles viewers that have conditions which crash no
   longer prevent the 'show' page from rendering; instead the
   viewer is ignored and removed from the available list.
   Fixes #25
6- Task forms for boutiques tasks will present list
   inputs in proper order.
   Fixes #830
7- Support for lists for File inputs in boutiques
   Fixes #831
  • Loading branch information
prioux committed Jun 27, 2019
1 parent c4e4364 commit 13718d5
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 31 deletions.
19 changes: 2 additions & 17 deletions Bourreau/script/cbrain_remote_ctl
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,7 @@
# script/rails server thin -d -e <environment> -p <port> -b 127.0.0.1 -P pidfile
#
# and finally removing the database.yml file. Any database.yml file
# already present before doing all this will be backed up in
#
# database.yml.cbrain_remote_bak.
#
# Note that if stdin contains nothing (zero bytes) the current
# database.yml file will be used, or the script will restore and use
# the backup file 'database.yml.cbrain_remote_bak'.
# already present before doing all this will be erased.
#
#
# To stop the Rails app:
Expand Down Expand Up @@ -197,25 +191,16 @@ fatal("Port argument must be a number greater than 1024 and less than 65530") un

db_yml_text = mode == "start" ? (STDIN.read || "") : ""
db_file = rails_home + "/config/database.yml"
db_file_bak = rails_home + "/config/database.yml.cbrain_remote_bak"

# Install or restore database.yml if necessary
db_exists = File.exist?(db_file)
bak_exists = File.exist?(db_file_bak)
blank_yml = db_yml_text !~ /\S/

if blank_yml # blank? use what db.yml is already here
if db_exists
# nothing to do
elsif bak_exists
File.rename(db_file_bak,db_file)
else
if ! db_exists
fatal("Could not find a database.yml file for the Rails application!")
end
else # db text is provided to us
if db_exists
File.rename(db_file,db_file_bak) # will crush existing bak file
end
# Optional: change stuff in it, depending on the environment
unless ENV['CBRAIN_FRONTEND_HOSTNAME'].nil? || ENV['CBRAIN_FRONTEND_HOSTNAME'] =~ /^\s*$/
db_yml_text.sub!(/hostname:\s*\S+/,"hostname: #{ENV['CBRAIN_FRONTEND_HOSTNAME']}")
Expand Down
2 changes: 1 addition & 1 deletion BrainPortal/app/helpers/resource_link_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ def link_to_user_with_tooltip(user, cur_user = current_user, options = {})
return "(None)" if user.blank?
cb_error "This method requires the first argument to be a User object." unless user.is_a?(User)
capture do
html_tool_tip(link_to_user_if_accessible(user,current_user,options), :offset_x => 60 ) do
html_tool_tip(link_to_user_if_accessible(user,current_user,options), :offset_x => 0, :offset_y => 20 ) do
(
"<div class=\"left_align\">\n" +
"#{h(user.full_name)}<br>\n" +
Expand Down
21 changes: 21 additions & 0 deletions BrainPortal/app/models/bourreau.rb
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,15 @@ def build_db_yml_for_tunnel(railsenv) #:nodoc:

public

# Utility method to sends a +stop_yourself+ command to a
# Bourreau RemoteResource, whether local or not.
def send_command_stop_yourself
command = RemoteCommand.new(
:command => 'stop_yourself',
)
send_command(command)
end

# Utility method to send a +get_task_outputs+ command to a
# Bourreau RemoteResource, whether local or not.
def send_command_get_task_outputs(task_id,run_number=nil,stdout_lim=nil,stderr_lim=nil)
Expand Down Expand Up @@ -393,6 +402,18 @@ def send_command_alter_tasks(tasks,new_task_status,extra_remote_commands = {})

protected

# This comaand is a bit dangerous: it will first trigger a +stop_workers+
# command to be sent locally, and then the rails app will kill itself with
# a TERM signal, thus exiting right after the current request. The user should
# really make sure the workers are inactive and there is no other background
# activity.
def self.process_command_stop_yourself(command)
process_command_stop_workers(
command.dup.tap { |com| com.command = "stop_workers" }
)
Process.kill('TERM',Process.pid) # the rails server will shut down after the current request
end

# Starts Bourreau worker processes.
# This also triggers a 'wakeup' command if they are already
# started.
Expand Down
18 changes: 17 additions & 1 deletion BrainPortal/app/models/cbrain_task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class CbrainTask < ApplicationRecord
validates_presence_of :tool_config_id

# Rails5 make belongs_to association required by default
# Task presets have bourreau id set to 0,
# Task presets have bourreau id set to 0,
# that's why the :bourreau assocition should be optionnal
belongs_to :bourreau, optional: true
belongs_to :user
Expand Down Expand Up @@ -889,8 +889,24 @@ def remove_workdir_archive #:nodoc:
archive.destroy
true
rescue
if archive
archive.tag_ids |= [ self.class.destroyed_archived_tag.id ]
end
true
end

# This returns (and if necessary creates the first time)
# a Tag object named 'TaskDestroyed', belonging to the main
# admin, that is used to mark any TaskWorkdirArchive that
# a user tried to delete but couldn't (e.g on unaccessible
# or read-only DPs etc). The admin can later find and delete them
# himself.
def self.destroyed_archived_tag #:nodoc:
@_destroyed_task_tag_ ||=
Tag.find_or_create_by( :name => 'TaskDestroyed',
:user_id => User.admin.id,
:group_id => User.admin.own_group.id )
end

end

2 changes: 2 additions & 0 deletions BrainPortal/app/models/userfile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,8 @@ def initialize_from_hash(atts = {}) #:nodoc:
def valid_for?(userfile) #:nodoc:
return true if @conditions.empty?
@conditions.all? { |condition| condition.call(userfile) }
rescue
false
end

def ==(other) #:nodoc:
Expand Down
31 changes: 22 additions & 9 deletions BrainPortal/config/console_rc/lib/interactive_bourreau_control.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def initialize(bourreaux_list = Bourreau.order(:id).all, term_width = nil)
@bourreaux = bourreaux_list
@width = term_width
if term_width.blank? || term_width.to_i < 1
numrows,numcols = Readline.get_screen_size rescue [25,120]
@width = numcols
_,numcols = Readline.get_screen_size rescue [25,120]
@width = numcols
end
@selected = {}
end
Expand Down Expand Up @@ -138,7 +138,7 @@ def interactive_control(initial_command = nil)
def process_user_letter(letter) #:nodoc:

# Validate the user input
if letter !~ /^([haombwitukygsrczqx]|\d+|exit|quit)$/
if letter !~ /^([haombwitukygsrczqxj]|\d+|exit|quit)$/
puts "Unknown command: #{letter} (ignored)"
return false
end
Expand All @@ -157,7 +157,10 @@ def process_user_letter(letter) #:nodoc:
W = starts workers
T = stops workers
U = stops workers and waits to make sure
K = stops bourreaux
K = stops bourreaux (using shell commands)
J = stops workers and bourreaux (using command control
messages; use this only if you're sure no workers
are active and the SSH masters are opened)
Y = cycle: stop workers and bourreaux then
start bourreaux and workers (replace operation queue)
Expand Down Expand Up @@ -226,13 +229,14 @@ def process_user_letter(letter) #:nodoc:
end

# Operation queue commands
if letter =~ /^[bwtku]$/
if letter =~ /^[bwtkuj]$/
@operations += " " if @operations.present?
@operations += "StartBourreaux" if letter == "b"
@operations += "StartWorkers" if letter == "w"
@operations += "StopBourreaux" if letter == "k"
@operations += "StopWorkers" if letter == "t"
@operations += "StopWorkersAndWait" if letter == "u"
@operations += "StopAllByCommand" if letter == "j"
return false
end

Expand Down Expand Up @@ -341,11 +345,12 @@ def process_user_letter(letter) #:nodoc:
def apply_operation(op, bou) #:nodoc:
printf "... %18s %-15s : ", op, bou.name
res,mess = [ false, "Unknown Operation #{op}" ]
res,mess = start_bourreaux(bou) if op == "StartBourreaux"
res,mess = start_bourreau(bou) if op == "StartBourreaux"
res,mess = start_workers(bou) if op == "StartWorkers"
res,mess = stop_bourreaux(bou) if op == "StopBourreaux"
res,mess = stop_bourreau(bou) if op == "StopBourreaux"
res,mess = stop_workers(bou) if op == "StopWorkers"
res,mess = stop_workers_and_wait(bou) if op == "StopWorkersAndWait"
res,mess = stop_all_by_command(bou) if op == "StopAllByCommand"
printf "%s\n", mess == nil ? "(nil)" : mess
[ res, mess ]
rescue IRB::Abort => ex
Expand Down Expand Up @@ -381,14 +386,22 @@ def stop_workers_and_wait(b) #:nodoc:
[ output.blank? , output.blank? ? "OK" : "Workers still active" ] # message text used to abort sequence, see earlier in code
end

def stop_bourreaux(b) #:nodoc:
def stop_bourreau(b) #:nodoc:
r1=b.stop rescue nil
r2=b.stop_tunnels rescue nil
b.update_attribute(:online, false)
[ !!(r1 && r2) , "App: #{r1 or false}\tSSH Master: #{r2 or false}" ]
end

def start_bourreaux(b) #:nodoc:
def stop_all_by_command(b)
r1=b.send_command_stop_yourself rescue "(Exc)"
r1=r1.command_execution_status if r1.is_a?(RemoteCommand)
r2=b.stop_tunnels rescue nil
b.update_attribute(:online, false)
[ ((r1 == "OK") && r2.present?), "App: #{r1 or false}\tSSH Master: #{r2 or false}" ]
end

def start_bourreau(b) #:nodoc:
r = b.start rescue nil
rev = "???"
if (r == true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
<%%
values = @task.params[name.to_sym] if name && values.nil?
values = values.is_a?(Enumerable) ? values.compact : [values].compact
first = values.pop
first = values.shift
%>
<ul class="tsk-prm-list">
<li>
Expand Down Expand Up @@ -343,7 +343,8 @@
)
<%- else -%>
# File input dropdown
dropdown.(id, id,
name = id <%= list ? '+ "[]"' : '' %>
dropdown.(id, name,
input_files.map { |f| [ f.id.to_s, f.name ] },
optional: <%= opt %>
)
Expand Down
5 changes: 4 additions & 1 deletion BrainPortal/public/javascripts/cbrain.js
Original file line number Diff line number Diff line change
Expand Up @@ -674,8 +674,11 @@
var trigger = $(this);
var tool_tip_id = trigger.data("tool-tip-id");
var tool_tip = $("#" + tool_tip_id);
var offset_x = trigger.data("offset-x") || '30';
var offset_x = trigger.data("offset-x");
var offset_y = trigger.data("offset-y") || '0';
if (typeof offset_x == 'undefined') {
offset_x = '30';
}

var x = trigger.position().left + parseInt(offset_x, 10);
var y = trigger.position().top + parseInt(offset_y, 10);
Expand Down

0 comments on commit 13718d5

Please sign in to comment.