Description:
- new install script - add comment in grader chain
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r254:8d92eda43960 - - 3 files changed: 27 inserted, 20 deleted

@@ -1,59 +1,44
1 #!/bin/sh
1 #!/bin/sh
2
2
3 + #installation script for cafe-grader, for ubuntu 16.04
4 +
3 echo "This script will install and configure Cafe grader."
5 echo "This script will install and configure Cafe grader."
4
6
5 - RUBY_VERSION=2.1.2
7 + RUBY_VERSION=2.3.7
6 - echo "This will install Ruby $RUBY_VERSION under RVM"
7 -
8 - echo "Installing required apts"
9 -
10 - sudo apt-get update
11 - sudo apt-get install mysql-server mysql-client \
12 - g++ gcc apache2 libmysqlclient20 build-essential \
13 - git-core openssl libreadline6 libreadline6-dev \
14 - zlib1g zlib1g-dev libssl-dev libyaml-dev libsqlite3-dev \
15 - sqlite3 libxml2-dev libxslt-dev autoconf libc6-dev \
16 - ncurses-dev automake libtool bison subversion \
17 - pkg-config curl nodejs unzip pyflakes ruby default-jdk \
18 - libmysqld-dev mercurial python-setuptools python-dev python3-numpy
19 -
20 - echo "Installing RVM"
21 - curl -k -L https://get.rvm.io | bash -s stable
22 - source ~/.rvm/scripts/rvm
23
8
24 echo "Installing Ruby $RUBY_VERSION in RVM"
9 echo "Installing Ruby $RUBY_VERSION in RVM"
25
10
26 rvm install $RUBY_VERSION
11 rvm install $RUBY_VERSION
27 rvm use $RUBY_VERSION
12 rvm use $RUBY_VERSION
28
13
29 echo "Fetching Cafe Grader from Git repositories"
14 echo "Fetching Cafe Grader from Git repositories"
30
15
31 echo "Fetching web interface"
16 echo "Fetching web interface"
32
17
33 mkdir cafe_grader
18 mkdir cafe_grader
34 cd cafe_grader
19 cd cafe_grader
35 - git clone -q git://github.com/jittat/cafe-grader-web.git web
20 + git clone -q git://github.com/cafe-grader-team/cafe-grader-web.git web
36
21
37 echo "Configuring rails app"
22 echo "Configuring rails app"
38
23
39 cp web/config/application.rb.SAMPLE web/config/application.rb
24 cp web/config/application.rb.SAMPLE web/config/application.rb
40 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
25 cp web/config/initializers/cafe_grader_config.rb.SAMPLE web/config/initializers/cafe_grader_config.rb
41
26
42 #replace UTC in application.rb with the system timezone
27 #replace UTC in application.rb with the system timezone
43 timezone='UTC'
28 timezone='UTC'
44 if [ -f '/etc/timezone' ]; then
29 if [ -f '/etc/timezone' ]; then
45 timezone=\"`cat /etc/timezone`\"
30 timezone=\"`cat /etc/timezone`\"
46 else
31 else
47 if [ -f '/etc/sysconfig/clock' ]; then
32 if [ -f '/etc/sysconfig/clock' ]; then
48 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
33 timezone=`grep -e '^TIMEZONE' /etc/sysconfig/clock | grep -o -e '\".*\"'`
49 fi
34 fi
50 fi
35 fi
51 replace="s!'UTC'!$timezone!g"
36 replace="s!'UTC'!$timezone!g"
52 sed -i $replace web/config/application.rb
37 sed -i $replace web/config/application.rb
53
38
54 echo "At this point we will need MySQL user and database."
39 echo "At this point we will need MySQL user and database."
55 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
40 echo "Have you created MySQL user and database for Cafe grader? (Y/N) "
56 read ch
41 read ch
57
42
58 if [ "$ch" = "n" -o "$ch" = "N" ]
43 if [ "$ch" = "n" -o "$ch" = "N" ]
59 then
44 then
@@ -111,57 +96,68
111 echo " pool: 5" >> config/database.yml
96 echo " pool: 5" >> config/database.yml
112 echo " username: $username" >> config/database.yml
97 echo " username: $username" >> config/database.yml
113 echo " password: $password" >> config/database.yml
98 echo " password: $password" >> config/database.yml
114 echo " host: localhost" >> config/database.yml
99 echo " host: localhost" >> config/database.yml
115 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
100 echo " socket: /var/run/mysqld/mysqld.sock" >> config/database.yml
116
101
117 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
102 echo "Object.instance_eval{remove_const :GRADER_ROOT_DIR}" >> config/initializers/cafe_grader_config.rb
118 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
103 echo "Object.instance_eval{remove_const :GRADING_RESULT_DIR}" >> config/initializers/cafe_grader_config.rb
119 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
104 echo "GRADER_ROOT_DIR = '$CAFE_PATH/judge'" >> config/initializers/cafe_grader_config.rb
120 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
105 echo "GRADING_RESULT_DIR = '$CAFE_PATH/judge/result'" >> config/initializers/cafe_grader_config.rb
121
106
122 echo "Installing required gems"
107 echo "Installing required gems"
123 gem install bundler
108 gem install bundler
124 bundle install
109 bundle install
125
110
126 echo "Running rake tasks to initialize database"
111 echo "Running rake tasks to initialize database"
127
112
128 rake db:migrate
113 rake db:migrate
129 rake db:seed
114 rake db:seed
130
115
131 echo "Running rake tasks to precompile the assets"
116 echo "Running rake tasks to precompile the assets"
132
117
133 rake assets:precompile
118 rake assets:precompile
134
119
120 + echo "setup the secret file"
121 + SECRET_A=`rake secret`
122 + SECRET_B=`rake secret`
123 + SECRET_C=`rake secret`
124 + echo "development:" > config/secrets.yml
125 + echo " secret_key_base: '$SECRET_A'" >> config/secrets.yml
126 + echo "test:" >> config/secrets.yml
127 + echo " secret_key_base: '$SECRET_B'" >> config/secrets.yml
128 + echo "production:" >> config/secrets.yml
129 + echo " secret_key_base: '$SECRET_C'" >> config/secrets.yml
130 +
135 echo "Intalling web interface complete..."
131 echo "Intalling web interface complete..."
136 echo
132 echo
137 echo "Fetching grader"
133 echo "Fetching grader"
138
134
139 cd ..
135 cd ..
140
136
141 mkdir judge
137 mkdir judge
142 cd judge
138 cd judge
143 - git clone -q git://github.com/jittat/cafe-grader-judge-scripts.git scripts
139 + git clone -q git://github.com/cafe-grader-team/cafe-grader-judge-scripts.git scripts
144 mkdir raw
140 mkdir raw
145 mkdir ev-exam
141 mkdir ev-exam
146 mkdir ev
142 mkdir ev
147 mkdir result
143 mkdir result
148 mkdir log
144 mkdir log
149
145
150 echo "Configuring grader"
146 echo "Configuring grader"
151
147
152 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
148 cp scripts/config/env_exam.rb.SAMPLE scripts/config/env_exam.rb
153 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
149 cp scripts/config/env_grading.rb.SAMPLE scripts/config/env_grading.rb
154
150
155 # create new environment.rb file
151 # create new environment.rb file
156 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
152 echo "RAILS_ROOT = '$CAFE_PATH/web'" > scripts/config/environment.rb
157 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
153 echo "GRADER_ROOT = '$CAFE_PATH/judge/scripts'" >> scripts/config/environment.rb
158 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
154 echo "require File.join(File.dirname(__FILE__),'../lib/boot')" >> scripts/config/environment.rb
159 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
155 echo "require File.dirname(__FILE__) + \"/env_#{GRADER_ENV}.rb\"" >> scripts/config/environment.rb
160
156
161 # compiling box
157 # compiling box
162 MACHINE_TYPE=`uname -m`
158 MACHINE_TYPE=`uname -m`
163 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
159 if [ ${MACHINE_TYPE} == 'x86_64' ]; then
164 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
160 gcc -std=c99 -o scripts/std-script/box scripts/std-script/box64-new.c
165 else
161 else
166 g++ -o scripts/std-script/box scripts/std-script/box.cc
162 g++ -o scripts/std-script/box scripts/std-script/box.cc
167 fi
163 fi
@@ -56,100 +56,108
56 # only look for c++.
56 # only look for c++.
57 if language == 'cpp'
57 if language == 'cpp'
58 language = 'c++'
58 language = 'c++'
59 end
59 end
60
60
61 # COMMENT: should it be only source.ext?
61 # COMMENT: should it be only source.ext?
62 if problem!=nil
62 if problem!=nil
63 source_name = "#{problem.name}.#{lang_ext}"
63 source_name = "#{problem.name}.#{lang_ext}"
64 else
64 else
65 source_name = "source.#{lang_ext}"
65 source_name = "source.#{lang_ext}"
66 end
66 end
67
67
68 grading_dir = @room_maker.produce_grading_room(submission)
68 grading_dir = @room_maker.produce_grading_room(submission)
69 @room_maker.save_source(submission,source_name)
69 @room_maker.save_source(submission,source_name)
70 problem_home = @room_maker.find_problem_home(submission)
70 problem_home = @room_maker.find_problem_home(submission)
71
71
72 # puts "GRADING DIR: #{grading_dir}"
72 # puts "GRADING DIR: #{grading_dir}"
73 # puts "PROBLEM DIR: #{problem_home}"
73 # puts "PROBLEM DIR: #{problem_home}"
74
74
75 if !FileTest.exist?(problem_home)
75 if !FileTest.exist?(problem_home)
76 puts "PROBLEM DIR: #{problem_home}"
76 puts "PROBLEM DIR: #{problem_home}"
77 raise "engine: No test data."
77 raise "engine: No test data."
78 end
78 end
79
79
80 + # copy the source script, using lock
80 dinit = DirInit::Manager.new(problem_home)
81 dinit = DirInit::Manager.new(problem_home)
81
82
83 + # lock the directory and copy the scripts
82 dinit.setup do
84 dinit.setup do
83 copy_log = copy_script(problem_home)
85 copy_log = copy_script(problem_home)
84 save_copy_log(problem_home,copy_log)
86 save_copy_log(problem_home,copy_log)
85 end
87 end
86
88
87 call_judge(problem_home,language,grading_dir,source_name)
89 call_judge(problem_home,language,grading_dir,source_name)
88
90
89 @reporter.report(submission,"#{grading_dir}/test-result")
91 @reporter.report(submission,"#{grading_dir}/test-result")
90
92
93 + # unlock the directory
91 dinit.teardown do
94 dinit.teardown do
92 copy_log = load_copy_log(problem_home)
95 copy_log = load_copy_log(problem_home)
93 clear_copy_log(problem_home)
96 clear_copy_log(problem_home)
94 clear_script(copy_log,problem_home)
97 clear_script(copy_log,problem_home)
95 end
98 end
96
99
97 rescue RuntimeError => msg
100 rescue RuntimeError => msg
98 @reporter.report_error(submission, msg)
101 @reporter.report_error(submission, msg)
99 puts "ERROR: #{msg}"
102 puts "ERROR: #{msg}"
100
103
101 ensure
104 ensure
102 @room_maker.clean_up(submission)
105 @room_maker.clean_up(submission)
103 Dir.chdir(current_dir) # this is really important
106 Dir.chdir(current_dir) # this is really important
104 end
107 end
105 end
108 end
106
109
107 protected
110 protected
108
111
109 def talk(str)
112 def talk(str)
110 if @config.talkative
113 if @config.talkative
111 puts str
114 puts str
112 end
115 end
113 end
116 end
114
117
118 + #change directory to problem_home
119 + #call the "judge" script
115 def call_judge(problem_home,language,grading_dir,fname)
120 def call_judge(problem_home,language,grading_dir,fname)
116 ENV['PROBLEM_HOME'] = problem_home
121 ENV['PROBLEM_HOME'] = problem_home
117 ENV['RUBYOPT'] = ''
122 ENV['RUBYOPT'] = ''
118
123
119 talk grading_dir
124 talk grading_dir
120 Dir.chdir grading_dir
125 Dir.chdir grading_dir
121 script_name = "#{problem_home}/script/judge"
126 script_name = "#{problem_home}/script/judge"
122 cmd = "#{script_name} #{language} #{fname}"
127 cmd = "#{script_name} #{language} #{fname}"
123 talk "CMD: #{cmd}"
128 talk "CMD: #{cmd}"
124 warn "ERROR: file does not exists #{script_name}" unless File.exists? script_name
129 warn "ERROR: file does not exists #{script_name}" unless File.exists? script_name
125 system(cmd)
130 system(cmd)
126 end
131 end
127
132
128 def get_std_script_dir
133 def get_std_script_dir
129 GRADER_ROOT + '/std-script'
134 GRADER_ROOT + '/std-script'
130 end
135 end
131
136
137 + #copy any script presented in std-script directory that is not in the problem_home
138 + #this allow a problem setter to provide their own version for each script
139 + #in case that they want to hack something
132 def copy_script(problem_home)
140 def copy_script(problem_home)
133 script_dir = "#{problem_home}/script"
141 script_dir = "#{problem_home}/script"
134 std_script_dir = get_std_script_dir
142 std_script_dir = get_std_script_dir
135
143
136 raise "engine: std-script directory not found" if !FileTest.exist?(std_script_dir)
144 raise "engine: std-script directory not found" if !FileTest.exist?(std_script_dir)
137
145
138 scripts = Dir[std_script_dir + '/*']
146 scripts = Dir[std_script_dir + '/*']
139
147
140 copied = []
148 copied = []
141
149
142 scripts.each do |s|
150 scripts.each do |s|
143 fname = File.basename(s)
151 fname = File.basename(s)
144 next if FileTest.directory?(s)
152 next if FileTest.directory?(s)
145 if !FileTest.exist?("#{script_dir}/#{fname}")
153 if !FileTest.exist?("#{script_dir}/#{fname}")
146 copied << fname
154 copied << fname
147 FileUtils.cp(s, "#{script_dir}", :preserve => true)
155 FileUtils.cp(s, "#{script_dir}", :preserve => true)
148 end
156 end
149 end
157 end
150
158
151 return copied
159 return copied
152 end
160 end
153
161
154 def copy_log_filename(problem_home)
162 def copy_log_filename(problem_home)
155 return File.join(problem_home, '.scripts_copied')
163 return File.join(problem_home, '.scripts_copied')
@@ -3,48 +3,51
3 #
3 #
4
4
5 module Grader
5 module Grader
6
6
7 class Runner
7 class Runner
8
8
9 def initialize(engine, grader_process=nil)
9 def initialize(engine, grader_process=nil)
10 @engine = engine
10 @engine = engine
11 @grader_process = grader_process
11 @grader_process = grader_process
12 end
12 end
13
13
14 def grade_oldest_task
14 def grade_oldest_task
15 task = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
15 task = Task.get_inqueue_and_change_status(Task::STATUS_GRADING)
16 if task!=nil
16 if task!=nil
17 @grader_process.report_active(task) if @grader_process!=nil
17 @grader_process.report_active(task) if @grader_process!=nil
18
18
19 submission = Submission.find(task.submission_id)
19 submission = Submission.find(task.submission_id)
20 @engine.grade(submission)
20 @engine.grade(submission)
21 task.status_complete!
21 task.status_complete!
22 @grader_process.report_inactive(task) if @grader_process!=nil
22 @grader_process.report_inactive(task) if @grader_process!=nil
23 end
23 end
24 return task
24 return task
25 end
25 end
26
26
27 + # grade a specified problem for the latest submission of each user
28 + # optionally, on all submission when options[:all_sub] is set
29 + # optionally, only submission that has error (use when the problem itself has some problem)
27 def grade_problem(problem, options={})
30 def grade_problem(problem, options={})
28 user_index = 0
31 user_index = 0
29 user_count = User.count
32 user_count = User.count
30 User.find_each do |u|
33 User.find_each do |u|
31 puts "user: #{u.login} (#{user_index}/#{user_count})"
34 puts "user: #{u.login} (#{user_index}/#{user_count})"
32 user_index += 1
35 user_index += 1
33 if options[:user_conditions]!=nil
36 if options[:user_conditions]!=nil
34 con_proc = options[:user_conditions]
37 con_proc = options[:user_conditions]
35 next if not con_proc.call(u)
38 next if not con_proc.call(u)
36 end
39 end
37 if options[:all_sub]
40 if options[:all_sub]
38 Submission.where(user_id: u.id,problem_id: problem.id).find_each do |sub|
41 Submission.where(user_id: u.id,problem_id: problem.id).find_each do |sub|
39 next if options[:only_err] and sub.grader_comment != 'error during grading'
42 next if options[:only_err] and sub.grader_comment != 'error during grading'
40 @engine.grade(sub)
43 @engine.grade(sub)
41 end
44 end
42 else
45 else
43 last_sub = Submission.find_last_by_user_and_problem(u.id,problem.id)
46 last_sub = Submission.find_last_by_user_and_problem(u.id,problem.id)
44 if last_sub!=nil
47 if last_sub!=nil
45 @engine.grade(last_sub) unless options[:only_err] and last_sub.grader_comment != 'error during grading'
48 @engine.grade(last_sub) unless options[:only_err] and last_sub.grader_comment != 'error during grading'
46 end
49 end
47 end
50 end
48 end
51 end
49 end
52 end
50
53
You need to be logged in to leave comments. Login now