diff options
| author | Daniel Nephin <dnephin@gmail.com> | 2016-03-16 21:47:17 -0400 |
|---|---|---|
| committer | Daniel Nephin <dnephin@gmail.com> | 2016-03-16 21:47:17 -0400 |
| commit | 8c4546f8c8f52bb2923834783a17beb5bb89a724 (patch) | |
| tree | a5ff2b1df031d66bce86e7a9b63ee48b32c835b2 | |
| parent | 7befe694bd21e3c54bb1d7825270ea4bd6864c13 (diff) | |
| parent | e576417217c367dfa0b5d33fe7f2886d67b0cbfb (diff) | |
| download | docker-py-8c4546f8c8f52bb2923834783a17beb5bb89a724.tar.gz | |
Merge pull request #994 from aanand/janLo-tmpfs-support
tmpfs support
| -rw-r--r-- | docker/utils/utils.py | 36 | ||||
| -rw-r--r-- | docs/hostconfig.md | 2 | ||||
| -rw-r--r-- | docs/tmpfs.md | 33 | ||||
| -rw-r--r-- | mkdocs.yml | 1 | ||||
| -rw-r--r-- | tests/integration/container_test.py | 16 | ||||
| -rw-r--r-- | tests/unit/container_test.py | 58 |
6 files changed, 145 insertions, 1 deletions
diff --git a/docker/utils/utils.py b/docker/utils/utils.py index d4393d5..c5914cf 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -337,6 +337,35 @@ 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( + 'Expected tmpfs value to be either a list or a dict, found: {}' + .format(type(tmpfs).__name__) + ) + + 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( + "Expected item in tmpfs list to be a string, found: {}" + .format(type(mount).__name__) + ) + + result[name] = options + return result + + def parse_repository_tag(repo_name): parts = repo_name.rsplit('@', 1) if len(parts) == 2: @@ -584,7 +613,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 = {} @@ -751,6 +780,11 @@ def create_host_config(binds=None, port_bindings=None, lxc_conf=None, host_config['CpuPeriod'] = cpu_period + if tmpfs: + if version_lt(version, '1.22'): + raise host_config_version_error('tmpfs', '1.22') + host_config["Tmpfs"] = convert_tmpfs_mounts(tmpfs) + return host_config diff --git a/docs/hostconfig.md b/docs/hostconfig.md index 4b841d5..19cd4ca 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 0000000..d8be9b6 --- /dev/null +++ b/docs/tmpfs.md @@ -0,0 +1,33 @@ +# Using tmpfs + +When creating a container, you can specify paths to be mounted with tmpfs using +the `tmpfs` argument to `create_host_config`, similarly to the `--tmpfs` +argument to `docker run`. + +This capability is supported in Docker Engine 1.10 and up. + +`tmpfs` can be either a list or a dictionary. If it's a list, each item is a +string specifying the path and (optionally) any configuration for the mount: + +```python +client.create_container( + 'busybox', 'ls', + host_config=client.create_host_config(tmpfs=[ + '/mnt/vol2', + '/mnt/vol1:size=3G,uid=1000' + ]) +) +``` + +Alternatively, if it's a dictionary, each key is a path and each value contains +the mount options: + +```python +client.create_container( + 'busybox', 'ls', + host_config=client.create_host_config(tmpfs={ + '/mnt/vol2': '', + '/mnt/vol1': 'size=3G,uid=1000' + }) +) +``` @@ -13,6 +13,7 @@ pages: - Host devices: host-devices.md - Host configuration: hostconfig.md - Network configuration: networks.md +- Using tmpfs: tmpfs.md - Using with boot2docker: boot2docker.md - Change Log: change_log.md - Contributing: contributing.md diff --git a/tests/integration/container_test.py b/tests/integration/container_test.py index a1498f9..940e5b8 100644 --- a/tests/integration/container_test.py +++ b/tests/integration/container_test.py @@ -382,6 +382,22 @@ class CreateContainerTest(helpers.BaseTestCase): sorted(['Foo', 'Other=one', 'Blank=']) ) + @requires_api_version('1.22') + def test_create_with_tmpfs(self): + tmpfs = { + '/tmp1': 'size=3M' + } + + container = self.client.create_container( + BUSYBOX, + ['echo'], + host_config=self.client.create_host_config( + tmpfs=tmpfs)) + + self.tmp_containers.append(container['Id']) + config = self.client.inspect_container(container) + assert config['HostConfig']['Tmpfs'] == tmpfs + class VolumeBindTest(helpers.BaseTestCase): def setUp(self): diff --git a/tests/unit/container_test.py b/tests/unit/container_test.py index 6e23f89..2a72c17 100644 --- a/tests/unit/container_test.py +++ b/tests/unit/container_test.py @@ -1016,6 +1016,64 @@ class CreateContainerTest(DockerClientTest): } }}''')) + @requires_api_version('1.22') + 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 + ) + + @requires_api_version('1.22') + 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): |
