diff --git a/docker/utils/utils.py b/docker/utils/utils.py index 61e5a8dc98..d43e7ab234 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -337,6 +337,33 @@ def convert_volume_binds(binds): return result +def convert_tmpfs_mounts(tmpfs): + if isinstance(tmpfs, dict): + return tmpfs + + if not isinstance(tmpfs, list): + raise ValueError( + 'Tmpfs spec must be a list' + ) + + result = {} + for mount in tmpfs: + if isinstance(mount, six.string_types): + if ":" in mount: + name, options = mount.split(":", 1) + else: + name = mount + options = "" + + else: + raise ValueError( + "Tmpfs spec have to be str, unicode or tuple" + ) + + result[name] = options + return result + + def parse_repository_tag(repo_name): parts = repo_name.rsplit('@', 1) if len(parts) == 2: @@ -582,7 +609,7 @@ def create_host_config(binds=None, port_bindings=None, lxc_conf=None, mem_limit=None, memswap_limit=None, mem_swappiness=None, cgroup_parent=None, group_add=None, cpu_quota=None, cpu_period=None, oom_kill_disable=False, shm_size=None, - version=None): + version=None, tmpfs=None): host_config = {} @@ -755,6 +782,9 @@ def create_host_config(binds=None, port_bindings=None, lxc_conf=None, host_config['CpuPeriod'] = cpu_period + if tmpfs: + host_config["Tmpfs"] = convert_tmpfs_mounts(tmpfs) + return host_config diff --git a/docs/hostconfig.md b/docs/hostconfig.md index 4b841d51a4..19cd4ca208 100644 --- a/docs/hostconfig.md +++ b/docs/hostconfig.md @@ -111,6 +111,8 @@ for example: container process will run as. * devices (list): Host device bindings. See [host devices](host-devices.md) for more information. +* tmpfs: Temporary filesystems to mouunt. See [Using tmpfs](tmpfs.md) for more + information. **Returns** (dict) HostConfig dictionary diff --git a/docs/tmpfs.md b/docs/tmpfs.md new file mode 100644 index 0000000000..34dadd9ee8 --- /dev/null +++ b/docs/tmpfs.md @@ -0,0 +1,32 @@ +# Using Tmpfs + +Tmpfs declaration is done with the `Client().create_container()` +method by declaring the mountpoints in the `host_config` section. + +This is available from docker 1.10. + +You can provide a list of declarations similar to the `--tmpfs` +option of the docker commandline client: + +```python +container_id = cli.create_container( + 'busybox', 'ls', + host_config=cli.create_host_config(tmpfs=[ + '/mnt/vol2', + '/mnt/vol1:size=3G,uid=1000' + ]) +) +``` + +You can alternatively specify tmpfs as a dict the docker remote +API uses: + +```python +container_id = cli.create_container( + 'busybox', 'ls', + host_config=cli.create_host_config(tmpfs={ + '/mnt/vol2': '', + '/mnt/vol1': 'size=3G,uid=1000' + }) +) +``` diff --git a/tests/unit/container_test.py b/tests/unit/container_test.py index c2b2573476..c94ebd19a7 100644 --- a/tests/unit/container_test.py +++ b/tests/unit/container_test.py @@ -1016,6 +1016,62 @@ def test_create_container_with_aliases(self): } }}''')) + def test_create_container_with_tmpfs_list(self): + + self.client.create_container( + 'busybox', 'true', host_config=self.client.create_host_config( + tmpfs=[ + "/tmp", + "/mnt:size=3G,uid=100" + ] + ) + ) + + args = fake_request.call_args + self.assertEqual(args[0][1], url_prefix + + 'containers/create') + expected_payload = self.base_create_payload() + expected_payload['HostConfig'] = self.client.create_host_config() + expected_payload['HostConfig']['Tmpfs'] = { + "/tmp": "", + "/mnt": "size=3G,uid=100" + } + self.assertEqual(json.loads(args[1]['data']), expected_payload) + self.assertEqual(args[1]['headers'], + {'Content-Type': 'application/json'}) + self.assertEqual( + args[1]['timeout'], + DEFAULT_TIMEOUT_SECONDS + ) + + def test_create_container_with_tmpfs_dict(self): + + self.client.create_container( + 'busybox', 'true', host_config=self.client.create_host_config( + tmpfs={ + "/tmp": "", + "/mnt": "size=3G,uid=100" + } + ) + ) + + args = fake_request.call_args + self.assertEqual(args[0][1], url_prefix + + 'containers/create') + expected_payload = self.base_create_payload() + expected_payload['HostConfig'] = self.client.create_host_config() + expected_payload['HostConfig']['Tmpfs'] = { + "/tmp": "", + "/mnt": "size=3G,uid=100" + } + self.assertEqual(json.loads(args[1]['data']), expected_payload) + self.assertEqual(args[1]['headers'], + {'Content-Type': 'application/json'}) + self.assertEqual( + args[1]['timeout'], + DEFAULT_TIMEOUT_SECONDS + ) + class ContainerTest(DockerClientTest): def test_list_containers(self):