Commit df05f9aa authored by Samuel GAIST's avatar Samuel GAIST

[dock] Added support for run arguments

This will allow to start a container with additional arguments
at run time.
parent a8871304
Pipeline #15776 canceled with stage
in 109 minutes and 50 seconds
......@@ -391,6 +391,10 @@ class Host(object):
args['volumes'] = [ v['bind'] for k, v in container.volumes.items() ]
host_config['binds'] = container.volumes
if container.run_arguments > 0:
for key, value in container.run_arguments.iteritems():
args[key] = value
# for HostConfig (keys are not arbitrary) - see:
# http://docker-py.readthedocs.io/en/latest/hostconfig/
args['host_config'] = self.client.create_host_config(**host_config)
......@@ -541,16 +545,50 @@ class Host(object):
#----------------------------------------------------------
def _merge_arguments(lha, rha):
"""
Recursively add the content of the rha dict to the lha dict. In case the
key is already present in lha, the value from lha gets priority.
"""
for rha_key, rha_value in rha.iteritems():
if rha_key not in lha:
lha[rha_key] = rha_value
else:
lha_value = lha[rha_key]
if isinstance(lha_value, dict) and isinstance(rha_value, dict):
_merge_arguments(lha_value, rha_value)
class Container:
def __init__(self, image, command):
self.image = image
self.command = command
self.volumes = {}
self.run_arguments = {}
self.archives = []
self._id = None
self._stats = None
def __str__(self):
return """Docker container:
Image {}
Command {}
Volumes{}
Run arguments{}
""".format(self.image,
self.command,
self.volumes,
self.run_arguments)
def set_run_arguments(self, run_arguments):
if run_arguments:
run_volumes = run_arguments.pop('volumes', None)
if run_volumes:
_merge_arguments(self.volumes, run_volumes)
self.run_arguments = run_arguments
def add_volume(self, path, mount_path, read_only=True):
self.volumes[path] = {
......
......@@ -303,6 +303,7 @@ class DockerExecutor(RemoteExecutor):
# Creation of the container
algorithm_container = self.host.create_container(processing_environment, cmd)
algorithm_container.copy_path(configuration_path, '/tmp')
algorithm_container.set_run_arguments(self.data.get('run_arguments', {}))
# Volumes
if not self.proxy_mode:
......
......@@ -225,6 +225,76 @@ class AsyncTest(unittest.TestCase):
self._run_cpulimit(4, 100, 3)
def test_run_arguments(self):
# Test that the runtime arguments are properly handled
file_path = os.path.realpath(__file__)
if file_path.endswith("pyc"):
file_path = file_path[:-1]
current_folder = os.path.dirname(file_path)
test_file_path = os.path.join(current_folder, '__init__.py')
test_container_path = '/test.py'
run_arguments = {
"mac_address": "12:12:12:12:12:12"
}
container_path = '/file_to_read.py'
volumes = { file_path: {
'bind': container_path,
'mode': 'ro'
},
test_file_path: {
'bind': '/dummy.py',
'mode': 'rw'
}
}
run_arguments["volumes"] = volumes
env_var = 'LICENSE_SERVER_ADDRESS'
run_arguments['environment'] = {
env_var: '312.123.412.255'
}
cmd = 'bash -c "cat {} ; echo ${}"'.format(container_path, env_var)
container = self.host.create_container(self.test_environment, cmd)
container.add_volume(test_file_path, test_container_path)
container.set_run_arguments(run_arguments)
self.host.start(container, virtual_memory_in_megabytes=4)
status = self.host.wait(container)
self.assertEqual(status, 0)
container_data = self.host.client.inspect_container(container._id)
mounts = container_data['Mounts']
configuration = container_data['Config']
environment = configuration['Env']
self.assertTrue(len(environment) > 0)
found = False
for env_value in environment:
if env_value.startswith(env_var):
found = True
break
self.assertTrue(found)
destinations = [mount['Destination'] for mount in mounts]
sources = [mount['Source'] for mount in mounts]
modes = [mount['Mode'] for mount in mounts]
self.assertItemsEqual(destinations, [test_container_path, container_path])
self.assertItemsEqual(sources, [test_file_path, file_path])
self.assertItemsEqual(modes, ['ro'] * 2)
with open(file_path) as test_content:
ref_output = '{}{}\n'.format(test_content.read(),
container.run_arguments['environment'][env_var])
self.assertEqual(self.host.stdout(container), ref_output)
self.assertEqual(self.host.stderr(container), '')
class HostTest(unittest.TestCase):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment