@@ -9,7 +9,9 @@ module KGrader | |||||
@root = @fs.assignment @course.name, @name | @root = @fs.assignment @course.name, @name | ||||
@config = @fs.load @fs.assignment_config(@course.name, @name) | @config = @fs.load @fs.assignment_config(@course.name, @name) | ||||
@manifest = build_manifest | |||||
verify_config | |||||
@manifest = get_manifest | |||||
rescue FilesystemError | rescue FilesystemError | ||||
raise AssignmentError, "unknown assignment: #{name}" | raise AssignmentError, "unknown assignment: #{name}" | ||||
end | end | ||||
@@ -18,22 +20,44 @@ module KGrader | |||||
@config['id'] || @name | @config['id'] || @name | ||||
end | end | ||||
def build_manifest | |||||
unless @config.include? 'manifest' | |||||
raise AssignmentError, "missing manifest: #{@name}" | |||||
def build_steps | |||||
@config['build'] | |||||
end | |||||
def tests | |||||
@config['grade'] | |||||
end | |||||
def report | |||||
@config['commit']['report'] || "report.txt" | |||||
end | |||||
def commit_message(student) | |||||
default = "adding grade report for #{name}: {student}" | |||||
template = @config['commit']['message'].clone || default | |||||
template['{student}'] = student | |||||
template | |||||
end | |||||
private | |||||
def verify_config | |||||
%w(stage build grade).each do |key| | |||||
unless @config.include? key | |||||
raise AssignmentError, "missing #{key} section in config: #{@name}" | |||||
end | |||||
end | end | ||||
end | |||||
def get_manifest | |||||
stage = @config['stage'] | |||||
raise AssignmentError, "chroot is not supported yet" if stage['chroot'] | |||||
manifest = @config['manifest'] | |||||
provided = manifest['provided'].map do |fn| | |||||
provided = stage['provided'].map do |fn| | |||||
{ :name => fn, :path => File.join(@root, 'provided', fn) } | { :name => fn, :path => File.join(@root, 'provided', fn) } | ||||
end | end | ||||
graded = manifest['graded'].map { |fn| { :name => fn } } | |||||
graded = stage['graded'].map { |fn| { :name => fn } } | |||||
{ | |||||
:provided => provided, | |||||
:graded => graded, | |||||
:report => manifest['report'] | |||||
} | |||||
{ :provided => provided, :graded => graded } | |||||
end | end | ||||
end | end | ||||
end | end |
@@ -5,16 +5,25 @@ module KGrader | |||||
@root = root | @root = root | ||||
end | end | ||||
def reset | |||||
FileUtils.rm_rf @root | |||||
end | |||||
def init | def init | ||||
FileUtils.mkdir_p @root | FileUtils.mkdir_p @root | ||||
end | end | ||||
def reset | |||||
FileUtils.rm_rf @root | |||||
def stage(source, target) | |||||
FileUtils.cp source, File.join(@root, target) | |||||
end | end | ||||
def stage(source, target) | |||||
puts "[chroot::stage] #{source} -> (jail)/#{target}" | |||||
def exec(command) | |||||
pid = Process.fork do | |||||
Dir.chdir @root | |||||
# TODO: rlimit in exec, umask? | |||||
Process.exec command | |||||
end | |||||
Process.waitpid pid, 0 | |||||
end | end | ||||
end | end | ||||
end | end |
@@ -48,30 +48,24 @@ module KGrader | |||||
end | end | ||||
def grade | def grade | ||||
# TODO: | |||||
# self.status = :ungraded | |||||
self.status = :ungraded | |||||
stage | stage | ||||
# [grade the stuff] | |||||
# [save report to gradefile] | |||||
# @fs.jail.reset | |||||
# FileUtils.touch pendingfile | |||||
# self.status = :graded | |||||
# return grade summary string | |||||
sleep rand / 2 | |||||
'100%' | |||||
build | |||||
test | |||||
save | |||||
# self.status = :graded # UNCOMMENT | |||||
# @fs.jail.reset # UNCOMMENT | |||||
# TODO: return grade summary string | |||||
end | end | ||||
def commit | def commit | ||||
# TODO: | |||||
# if status == :graded && File.exists? pendingfile | |||||
# [copy gradefile to repo] | |||||
# @course.backend.commit repo, <message>, <gradefile path> | |||||
# FileUtils.rm pendingfile | |||||
# end | |||||
sleep rand / 2 | |||||
nil | |||||
if status == :graded && File.exists?(pendingfile) | |||||
target = File.join(repo, @assignment.report) | |||||
message = @assignment.commit_message @student | |||||
FileUtils.cp gradefile, target | |||||
@course.backend.commit repo, message, target | |||||
FileUtils.rm pendingfile | |||||
end | |||||
end | end | ||||
private | private | ||||
@@ -118,5 +112,22 @@ module KGrader | |||||
@fs.jail.stage File.join(repo, entry[:name]), entry[:name] | @fs.jail.stage File.join(repo, entry[:name]), entry[:name] | ||||
end | end | ||||
end | end | ||||
def build | |||||
@assignment.build_steps.each do |command| | |||||
@fs.jail.exec command | |||||
end | |||||
end | |||||
def test | |||||
@assignment.tests.each do |script| | |||||
# TODO: execute script in jail | |||||
end | |||||
end | |||||
def save | |||||
# TODO: save gradefile | |||||
FileUtils.touch pendingfile | |||||
end | |||||
end | end | ||||
end | end |
@@ -1 +1 @@ | |||||
Subproject commit 438e509e4c9097894f275dd66a5ae37bbcb62c24 | |||||
Subproject commit f9cb0aabbe48368ef7a8db6c43e7d81e71d2c4fa |