diff --git a/docker/api/container.py b/docker/api/container.py index 6a764fbf..d8a23193 100644 --- a/docker/api/container.py +++ b/docker/api/container.py @@ -547,6 +547,8 @@ class ContainerApiMixin(object): security_opt (:py:class:`list`): A list of string values to customize labels for MLS systems, such as SELinux. shm_size (str or int): Size of /dev/shm (e.g. ``1G``). + storage_opt (dict): Storage driver options per container as a + key-value mapping. sysctls (dict): Kernel parameters to set in the container. tmpfs (dict): Temporary filesystems to mount, as a dictionary mapping a path inside the container to options for that path. diff --git a/docker/models/containers.py b/docker/models/containers.py index c4a4add4..8602531e 100644 --- a/docker/models/containers.py +++ b/docker/models/containers.py @@ -585,6 +585,8 @@ class ContainerCollection(Collection): Default: ``False``. stop_signal (str): The stop signal to use to stop the container (e.g. ``SIGINT``). + storage_opt (dict): Storage driver options per container as a + key-value mapping. sysctls (dict): Kernel parameters to set in the container. tmpfs (dict): Temporary filesystems to mount, as a dictionary mapping a path inside the container to options for that path. @@ -828,6 +830,7 @@ RUN_HOST_CONFIG_KWARGS = [ 'restart_policy', 'security_opt', 'shm_size', + 'storage_opt', 'sysctls', 'tmpfs', 'ulimits', diff --git a/docker/types/containers.py b/docker/types/containers.py index 3c0e41e0..9a8d1574 100644 --- a/docker/types/containers.py +++ b/docker/types/containers.py @@ -117,7 +117,7 @@ class HostConfig(dict): oom_kill_disable=False, shm_size=None, sysctls=None, tmpfs=None, oom_score_adj=None, dns_opt=None, cpu_shares=None, cpuset_cpus=None, userns_mode=None, pids_limit=None, - isolation=None, auto_remove=False): + isolation=None, auto_remove=False, storage_opt=None): if mem_limit is not None: self['Memory'] = parse_bytes(mem_limit) @@ -412,6 +412,11 @@ class HostConfig(dict): raise host_config_version_error('auto_remove', '1.25') self['AutoRemove'] = auto_remove + if storage_opt is not None: + if version_lt(version, '1.24'): + raise host_config_version_error('storage_opt', '1.24') + self['StorageOpt'] = storage_opt + 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 3cede45d..42a5b4ad 100644 --- a/tests/integration/api_container_test.py +++ b/tests/integration/api_container_test.py @@ -422,6 +422,22 @@ class CreateContainerTest(BaseAPIIntegrationTest): config = self.client.inspect_container(container) assert config['Config']['StopTimeout'] == 25 + @requires_api_version('1.24') + def test_create_with_storage_opt(self): + if self.client.info()['Driver'] == 'aufs': + return pytest.skip('Not supported on AUFS') + host_config = self.client.create_host_config( + storage_opt={'size': '120G'} + ) + container = self.client.create_container( + BUSYBOX, ['echo', 'test'], host_config=host_config + ) + self.tmp_containers.append(container) + config = self.client.inspect_container(container) + assert config['HostConfig']['StorageOpt'] == { + 'size': '120G' + } + class VolumeBindTest(BaseAPIIntegrationTest): def setUp(self): diff --git a/tests/integration/base.py b/tests/integration/base.py index 8b75acc9..503efc5b 100644 --- a/tests/integration/base.py +++ b/tests/integration/base.py @@ -68,6 +68,10 @@ class BaseAPIIntegrationTest(BaseIntegrationTest): version=TEST_API_VERSION, timeout=60, **kwargs_from_env() ) + def tearDown(self): + super(BaseAPIIntegrationTest, self).tearDown() + self.client.close() + def run_container(self, *args, **kwargs): container = self.client.create_container(*args, **kwargs) self.tmp_containers.append(container)