docker_client file copy work in progress

This commit is contained in:
Ralf Teusner
2016-01-25 10:36:32 +01:00
parent c77d52c0e4
commit 113f765246

View File

@ -2,7 +2,7 @@ require 'concurrent'
require 'pathname' require 'pathname'
class DockerClient class DockerClient
CONTAINER_WORKSPACE_PATH = '/workspace' CONTAINER_WORKSPACE_PATH = '/workspace' #'/home/python/workspace' #'/tmp/workspace'
DEFAULT_MEMORY_LIMIT = 256 DEFAULT_MEMORY_LIMIT = 256
# Ralf: I suggest to replace this with the environment variable. Ask Hauke why this is not the case! # Ralf: I suggest to replace this with the environment variable. Ask Hauke why this is not the case!
LOCAL_WORKSPACE_ROOT = Rails.root.join('tmp', 'files', Rails.env) LOCAL_WORKSPACE_ROOT = Rails.root.join('tmp', 'files', Rails.env)
@ -21,11 +21,14 @@ class DockerClient
end end
def self.clean_container_workspace(container) def self.clean_container_workspace(container)
container.exec(['bash', '-c', 'rm -rf ' + CONTAINER_WORKSPACE_PATH])
=begin
local_workspace_path = local_workspace_path(container) local_workspace_path = local_workspace_path(container)
if local_workspace_path && Pathname.new(local_workspace_path).exist? if local_workspace_path && Pathname.new(local_workspace_path).exist?
Pathname.new(local_workspace_path).children.each{ |p| p.rmtree} Pathname.new(local_workspace_path).children.each{ |p| p.rmtree}
#FileUtils.rmdir(Pathname.new(local_workspace_path)) #FileUtils.rmdir(Pathname.new(local_workspace_path))
end end
=end
end end
def command_substitutions(filename) def command_substitutions(filename)
@ -42,6 +45,8 @@ class DockerClient
'Image' => find_image_by_tag(execution_environment.docker_image).info['RepoTags'].first, 'Image' => find_image_by_tag(execution_environment.docker_image).info['RepoTags'].first,
'Memory' => execution_environment.memory_limit.megabytes, 'Memory' => execution_environment.memory_limit.megabytes,
'NetworkDisabled' => !execution_environment.network_enabled?, 'NetworkDisabled' => !execution_environment.network_enabled?,
#'HostConfig' => { 'CpusetCpus' => '0', 'CpuQuota' => 10000 },
#DockerClient.config['allowed_cpus']
'OpenStdin' => true, 'OpenStdin' => true,
'StdinOnce' => true, 'StdinOnce' => true,
# required to expose standard streams over websocket # required to expose standard streams over websocket
@ -88,12 +93,12 @@ class DockerClient
def self.create_container(execution_environment) def self.create_container(execution_environment)
tries ||= 0 tries ||= 0
Rails.logger.info "docker_client: self.create_container with creation options:" #Rails.logger.info "docker_client: self.create_container with creation options:"
Rails.logger.info(container_creation_options(execution_environment)) #Rails.logger.info(container_creation_options(execution_environment))
container = Docker::Container.create(container_creation_options(execution_environment)) container = Docker::Container.create(container_creation_options(execution_environment))
local_workspace_path = generate_local_workspace_path local_workspace_path = generate_local_workspace_path
# container.start always creates the passed local_workspace_path on disk. Seems like we have to live with that, therefore we can also just create the empty folder ourselves. # container.start always creates the passed local_workspace_path on disk. Seems like we have to live with that, therefore we can also just create the empty folder ourselves.
FileUtils.mkdir(local_workspace_path) # FileUtils.mkdir(local_workspace_path)
container.start(container_start_options(execution_environment, local_workspace_path)) container.start(container_start_options(execution_environment, local_workspace_path))
container.start_time = Time.now container.start_time = Time.now
container.status = :created container.status = :created
@ -129,6 +134,7 @@ class DockerClient
private :create_workspace_file private :create_workspace_file
def create_workspace_files_transmit(container, submission) def create_workspace_files_transmit(container, submission)
begin
# create a temporary dir, put all files in it, and put it into the container. the dir is automatically removed when leaving the block. # create a temporary dir, put all files in it, and put it into the container. the dir is automatically removed when leaving the block.
Dir.mktmpdir {|dir| Dir.mktmpdir {|dir|
submission.collect_files.each do |file| submission.collect_files.each do |file|
@ -137,12 +143,42 @@ class DockerClient
disk_file.close disk_file.close
end end
# tar the files in dir and put the tar to CONTAINER_WORKSPACE_PATH in the container
container.archive_in(dir, CONTAINER_WORKSPACE_PATH, overwrite: false)
# untar the tar file placed in the CONTAINER_WORKSPACE_PATH begin
container.exec(['bash', '-c', 'tar -xf ' + CONTAINER_WORKSPACE_PATH + '/' + dir.split('/tmp/')[1] + ' -C ' + CONTAINER_WORKSPACE_PATH]) # create target folder
container.exec(['bash', '-c', 'mkdir ' + CONTAINER_WORKSPACE_PATH])
#container.exec(['bash', '-c', 'chown -R python ' + CONTAINER_WORKSPACE_PATH])
#container.exec(['bash', '-c', 'chgrp -G python ' + CONTAINER_WORKSPACE_PATH])
rescue StandardError => error
Rails.logger.error('create workspace folder: Rescued from StandardError: ' + error.to_s)
end
#sleep 1000
begin
# tar the files in dir and put the tar to CONTAINER_WORKSPACE_PATH in the container
container.archive_in(dir, CONTAINER_WORKSPACE_PATH, overwrite: false)
rescue StandardError => error
Rails.logger.error('insert tar: Rescued from StandardError: ' + error.to_s)
end
Rails.logger.info('command: tar -xf ' + CONTAINER_WORKSPACE_PATH + '/' + dir.split('/tmp/')[1] + ' -C ' + CONTAINER_WORKSPACE_PATH)
begin
# untar the tar file placed in the CONTAINER_WORKSPACE_PATH
container.exec(['bash', '-c', 'tar -xf ' + CONTAINER_WORKSPACE_PATH + '/' + dir.split('/tmp/')[1] + ' -C ' + CONTAINER_WORKSPACE_PATH])
rescue StandardError => error
Rails.logger.error('untar: Rescued from StandardError: ' + error.to_s)
end
sleep 1000
} }
rescue StandardError => error
Rails.logger.error('create_workspace_files_transmit: Rescued from StandardError: ' + error.to_s)
end
end end
def self.destroy_container(container) def self.destroy_container(container)
@ -208,8 +244,8 @@ class DockerClient
We need to start a second thread to kill the websocket connection, We need to start a second thread to kill the websocket connection,
as it is impossible to determine whether further input is requested. as it is impossible to determine whether further input is requested.
""" """
#begin
@thread = Thread.new do @thread = Thread.new do
#begin
timeout = @execution_environment.permitted_execution_time.to_i # seconds timeout = @execution_environment.permitted_execution_time.to_i # seconds
sleep(timeout) sleep(timeout)
if container.status != :returned if container.status != :returned
@ -220,11 +256,11 @@ class DockerClient
end end
kill_container(container) kill_container(container)
end end
#ensure
# guarantee that the thread is releasing the DB connection after it is done
# ActiveRecord::Base.connectionpool.releaseconnection
#end
end end
#ensure
# guarantee that the thread is releasing the DB connection after it is done
# ActiveRecord::Base.connectionpool.releaseconnection
#end
end end
def exit_container(container) def exit_container(container)