summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <joffrey@docker.com>2017-10-24 16:17:25 -0700
committerJoffrey F <f.joffrey@gmail.com>2017-10-24 18:59:01 -0700
commit5552deed8620fa5652fbc899f2e94358ef82f844 (patch)
treecf0a9f15125dacda541d46c170a51318d383639a
parent877fc817d74a3a44501d07d32ef67dcf95787898 (diff)
downloaddocker-py-5552deed8620fa5652fbc899f2e94358ef82f844.tar.gz
Add support for mounts in HostConfig
Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r--docker/api/container.py4
-rw-r--r--docker/models/containers.py5
-rw-r--r--docker/types/containers.py7
-rw-r--r--tests/integration/api_container_test.py65
4 files changed, 80 insertions, 1 deletions
diff --git a/docker/api/container.py b/docker/api/container.py
index 918f8a3..f3c33c9 100644
--- a/docker/api/container.py
+++ b/docker/api/container.py
@@ -529,6 +529,10 @@ class ContainerApiMixin(object):
behavior. Accepts number between 0 and 100.
memswap_limit (str or int): Maximum amount of memory + swap a
container is allowed to consume.
+ mounts (:py:class:`list`): Specification for mounts to be added to
+ the container. More powerful alternative to ``binds``. Each
+ item in the list is expected to be a
+ :py:class:`docker.types.Mount` object.
network_mode (str): One of:
- ``bridge`` Create a new network stack for the container on
diff --git a/docker/models/containers.py b/docker/models/containers.py
index 688decc..ea8c10b 100644
--- a/docker/models/containers.py
+++ b/docker/models/containers.py
@@ -549,6 +549,10 @@ class ContainerCollection(Collection):
behavior. Accepts number between 0 and 100.
memswap_limit (str or int): Maximum amount of memory + swap a
container is allowed to consume.
+ mounts (:py:class:`list`): Specification for mounts to be added to
+ the container. More powerful alternative to ``volumes``. Each
+ item in the list is expected to be a
+ :py:class:`docker.types.Mount` object.
name (str): The name for this container.
nano_cpus (int): CPU quota in units of 10-9 CPUs.
network (str): Name of the network this container will be connected
@@ -888,6 +892,7 @@ RUN_HOST_CONFIG_KWARGS = [
'mem_reservation',
'mem_swappiness',
'memswap_limit',
+ 'mounts',
'nano_cpus',
'network_mode',
'oom_kill_disable',
diff --git a/docker/types/containers.py b/docker/types/containers.py
index 030e292..3fc13d9 100644
--- a/docker/types/containers.py
+++ b/docker/types/containers.py
@@ -120,7 +120,7 @@ class HostConfig(dict):
isolation=None, auto_remove=False, storage_opt=None,
init=None, init_path=None, volume_driver=None,
cpu_count=None, cpu_percent=None, nano_cpus=None,
- cpuset_mems=None, runtime=None):
+ cpuset_mems=None, runtime=None, mounts=None):
if mem_limit is not None:
self['Memory'] = parse_bytes(mem_limit)
@@ -478,6 +478,11 @@ class HostConfig(dict):
raise host_config_version_error('runtime', '1.25')
self['Runtime'] = runtime
+ if mounts is not None:
+ if version_lt(version, '1.30'):
+ raise host_config_version_error('mounts', '1.30')
+ self['Mounts'] = mounts
+
def host_config_type_error(param, param_value, expected):
error_msg = 'Invalid type for {0} param: expected {1} but found {2}'
diff --git a/tests/integration/api_container_test.py b/tests/integration/api_container_test.py
index a972c1c..f03ccdb 100644
--- a/tests/integration/api_container_test.py
+++ b/tests/integration/api_container_test.py
@@ -522,6 +522,71 @@ class VolumeBindTest(BaseAPIIntegrationTest):
inspect_data = self.client.inspect_container(container)
self.check_container_data(inspect_data, False)
+ @pytest.mark.xfail(
+ IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform'
+ )
+ @requires_api_version('1.30')
+ def test_create_with_mounts(self):
+ mount = docker.types.Mount(
+ type="bind", source=self.mount_origin, target=self.mount_dest
+ )
+ host_config = self.client.create_host_config(mounts=[mount])
+ container = self.run_container(
+ BUSYBOX, ['ls', self.mount_dest],
+ host_config=host_config
+ )
+ assert container
+ logs = self.client.logs(container)
+ if six.PY3:
+ logs = logs.decode('utf-8')
+ assert self.filename in logs
+ inspect_data = self.client.inspect_container(container)
+ self.check_container_data(inspect_data, True)
+
+ @pytest.mark.xfail(
+ IS_WINDOWS_PLATFORM, reason='Test not designed for Windows platform'
+ )
+ @requires_api_version('1.30')
+ def test_create_with_mounts_ro(self):
+ mount = docker.types.Mount(
+ type="bind", source=self.mount_origin, target=self.mount_dest,
+ read_only=True
+ )
+ host_config = self.client.create_host_config(mounts=[mount])
+ container = self.run_container(
+ BUSYBOX, ['ls', self.mount_dest],
+ host_config=host_config
+ )
+ assert container
+ logs = self.client.logs(container)
+ if six.PY3:
+ logs = logs.decode('utf-8')
+ assert self.filename in logs
+ inspect_data = self.client.inspect_container(container)
+ self.check_container_data(inspect_data, False)
+
+ @requires_api_version('1.30')
+ def test_create_with_volume_mount(self):
+ mount = docker.types.Mount(
+ type="volume", source=helpers.random_name(),
+ target=self.mount_dest, labels={'com.dockerpy.test': 'true'}
+ )
+ host_config = self.client.create_host_config(mounts=[mount])
+ container = self.client.create_container(
+ BUSYBOX, ['true'], host_config=host_config,
+ )
+ assert container
+ inspect_data = self.client.inspect_container(container)
+ assert 'Mounts' in inspect_data
+ filtered = list(filter(
+ lambda x: x['Destination'] == self.mount_dest,
+ inspect_data['Mounts']
+ ))
+ assert len(filtered) == 1
+ mount_data = filtered[0]
+ assert mount['Source'] == mount_data['Name']
+ assert mount_data['RW'] is True
+
def check_container_data(self, inspect_data, rw):
if docker.utils.compare_version('1.20', self.client._version) < 0:
self.assertIn('Volumes', inspect_data)