summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Nephin <dnephin@gmail.com>2016-03-16 21:47:17 -0400
committerDaniel Nephin <dnephin@gmail.com>2016-03-16 21:47:17 -0400
commit8c4546f8c8f52bb2923834783a17beb5bb89a724 (patch)
treea5ff2b1df031d66bce86e7a9b63ee48b32c835b2
parent7befe694bd21e3c54bb1d7825270ea4bd6864c13 (diff)
parente576417217c367dfa0b5d33fe7f2886d67b0cbfb (diff)
downloaddocker-py-8c4546f8c8f52bb2923834783a17beb5bb89a724.tar.gz
Merge pull request #994 from aanand/janLo-tmpfs-support
tmpfs support
-rw-r--r--docker/utils/utils.py36
-rw-r--r--docs/hostconfig.md2
-rw-r--r--docs/tmpfs.md33
-rw-r--r--mkdocs.yml1
-rw-r--r--tests/integration/container_test.py16
-rw-r--r--tests/unit/container_test.py58
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'
+ })
+)
+```
diff --git a/mkdocs.yml b/mkdocs.yml
index c6bfae1..64e9e6c 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -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):