Editor: Allow file retrieval after code run
This commit is contained in:

committed by
Sebastian Serth

parent
fb9672c7a4
commit
60078701f5
@ -146,7 +146,7 @@ class Runner::Connection
|
||||
@strategy.destroy_at_management
|
||||
@error = Runner::Error::ExecutionTimeout.new('Execution exceeded its time limit')
|
||||
when :terminated_by_codeocean, :terminated_by_management
|
||||
@exit_callback.call @exit_code
|
||||
@exit_callback.call @exit_code, @strategy.retrieve_files
|
||||
when :terminated_by_client, :error
|
||||
@strategy.destroy_at_management
|
||||
else # :established
|
||||
|
@ -33,6 +33,14 @@ class Runner::Strategy
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def retrieve_files(_path:, _recursive:, privileged_execution:)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def download_file(_file, privileged_execution:, &_block)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def attach_to_execution(_command, _event_loop, _starting_time, privileged_execution:)
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
@ -104,6 +104,10 @@ class Runner::Strategy::DockerContainerPool < Runner::Strategy
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Finished copying files" }
|
||||
end
|
||||
|
||||
def retrieve_files(_path:, _recursive:, privileged_execution:)
|
||||
# The DockerContainerPool does not support retrieving files from the runner.
|
||||
end
|
||||
|
||||
def attach_to_execution(command, event_loop, starting_time, privileged_execution: false) # rubocop:disable Lint/UnusedMethodArgument for the keyword argument
|
||||
reset_inactivity_timer
|
||||
|
||||
|
@ -25,6 +25,12 @@ class Runner::Strategy::Null < Runner::Strategy
|
||||
|
||||
def copy_files(_files); end
|
||||
|
||||
def retrieve_files(_path:, _recursive:, privileged_execution: false); end
|
||||
|
||||
def download_file(_file, privileged_execution: false, &_block) # rubocop:disable Lint/UnusedMethodArgument for the keyword argument
|
||||
raise Runner::Error.new
|
||||
end
|
||||
|
||||
def attach_to_execution(command, event_loop, starting_time, privileged_execution: false) # rubocop:disable Lint/UnusedMethodArgument for the keyword argument
|
||||
socket = Connection.new(nil, self, event_loop)
|
||||
# We don't want to return an error if the execution environment is changed
|
||||
|
@ -132,6 +132,64 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Finished copying files" }
|
||||
end
|
||||
|
||||
def retrieve_files(path: './', recursive: true, privileged_execution: false)
|
||||
url = "#{runner_url}/files"
|
||||
params = {
|
||||
path: path,
|
||||
recursive: recursive,
|
||||
privilegedExecution: privileged_execution || @execution_environment.privileged_execution,
|
||||
}
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Retrieving files at #{runner_url} with #{params}" }
|
||||
response = self.class.http_connection.get url, params
|
||||
case response.status
|
||||
when 200
|
||||
JSON.parse(response.body)
|
||||
when 424
|
||||
raise Runner::Error::WorkspaceError.new("The path #{path} is not available or could not be read.")
|
||||
else
|
||||
self.class.handle_error response
|
||||
end
|
||||
rescue Faraday::Error => e
|
||||
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||
ensure
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Finished listing files" }
|
||||
end
|
||||
|
||||
def download_file(file, privileged_execution: false, &block)
|
||||
url = "#{runner_url}/files/raw"
|
||||
params = {
|
||||
path: file,
|
||||
privilegedExecution: privileged_execution || @execution_environment.privileged_execution,
|
||||
}
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Download file #{params} from #{runner_url}" }
|
||||
response = self.class.new_http_connection.get url, params do |request|
|
||||
content_length = nil
|
||||
content_type = nil
|
||||
next if block.blank?
|
||||
|
||||
request.options.on_data = proc do |chunk, _overall_received_bytes, env|
|
||||
next unless env.success?
|
||||
|
||||
content_length ||= env.response_headers['Content-Length'].presence&.to_i
|
||||
content_type ||= env.response_headers['Content-Type'].presence || 'application/octet-stream'
|
||||
yield chunk, content_length, content_type
|
||||
end
|
||||
request.options
|
||||
end
|
||||
case response.status
|
||||
when 200
|
||||
response.body
|
||||
when 424
|
||||
raise Runner::Error::WorkspaceError.new("The file #{file} is not available or could not be read.")
|
||||
else
|
||||
self.class.handle_error response
|
||||
end
|
||||
rescue Faraday::Error => e
|
||||
raise Runner::Error::FaradayError.new("Request to Poseidon failed: #{e.inspect}")
|
||||
ensure
|
||||
Rails.logger.debug { "#{Time.zone.now.getutc.inspect}: Finished downloading file" }
|
||||
end
|
||||
|
||||
def attach_to_execution(command, event_loop, starting_time, privileged_execution: false)
|
||||
websocket_url = execute_command(command, privileged_execution: privileged_execution)
|
||||
socket = Connection.new(websocket_url, self, event_loop)
|
||||
@ -232,6 +290,12 @@ class Runner::Strategy::Poseidon < Runner::Strategy
|
||||
end
|
||||
end
|
||||
|
||||
def self.new_http_connection
|
||||
Faraday.new(ssl: {ca_file: config[:ca_file]}, headers: headers) do |faraday|
|
||||
faraday.adapter :net_http
|
||||
end
|
||||
end
|
||||
|
||||
def self.parse(response)
|
||||
JSON.parse(response.body).deep_symbolize_keys
|
||||
rescue JSON::ParserError => e
|
||||
|
Reference in New Issue
Block a user