From 40026b78d4f8c421f5f18f17e0fb3e73135a4029 Mon Sep 17 00:00:00 2001 From: Mark Adams Date: Thu, 3 Mar 2016 21:20:16 -0600 Subject: [PATCH] Add support for tmpfs The ability to create a tmpfs mountpoint was introduced in Docker 1.10 (API version 1.22). This commit adds a tmpfs argument to create_container() to implement this functionality and updates the associated documentation. Signed-off-by: Mark Adams --- docker/api/container.py | 4 ++-- docker/utils/utils.py | 18 +++++++++++++++++- docs/api.md | 1 + tests/unit/container_test.py | 22 ++++++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/docker/api/container.py b/docker/api/container.py index ef17c27c17..cfabc1a961 100644 --- a/docker/api/container.py +++ b/docker/api/container.py @@ -99,7 +99,7 @@ def create_container(self, image, command=None, hostname=None, user=None, cpu_shares=None, working_dir=None, domainname=None, memswap_limit=None, cpuset=None, host_config=None, mac_address=None, labels=None, volume_driver=None, - stop_signal=None, networking_config=None): + stop_signal=None, networking_config=None, tmpfs=None): if isinstance(volumes, six.string_types): volumes = [volumes, ] @@ -114,7 +114,7 @@ def create_container(self, image, command=None, hostname=None, user=None, tty, mem_limit, ports, environment, dns, volumes, volumes_from, network_disabled, entrypoint, cpu_shares, working_dir, domainname, memswap_limit, cpuset, host_config, mac_address, labels, - volume_driver, stop_signal, networking_config, + volume_driver, stop_signal, networking_config, tmpfs ) return self.create_container_from_config(config, name) diff --git a/docker/utils/utils.py b/docker/utils/utils.py index bc26ce82f7..1a43ba4025 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -832,6 +832,7 @@ def create_container_config( entrypoint=None, cpu_shares=None, working_dir=None, domainname=None, memswap_limit=None, cpuset=None, host_config=None, mac_address=None, labels=None, volume_driver=None, stop_signal=None, networking_config=None, + tmpfs=None ): if isinstance(command, six.string_types): command = split_command(command) @@ -852,6 +853,11 @@ def create_container_config( 'stop_signal was only introduced in API version 1.21' ) + if tmpfs is not None and compare_version('1.22', version) < 0: + raise errors.InvalidVersion( + 'tmpfs was only introduced in API version 1.22' + ) + if compare_version('1.19', version) < 0: if volume_driver is not None: raise errors.InvalidVersion( @@ -900,6 +906,15 @@ def create_container_config( volumes_dict[vol] = {} volumes = volumes_dict + if isinstance(tmpfs, six.string_types): + tmpfs = [tmpfs, ] + + if isinstance(tmpfs, list): + tmpfs_dict = {} + for tmpdir in tmpfs: + tmpfs_dict[tmpdir] = '' + tmpfs = tmpfs_dict + if volumes_from: if not isinstance(volumes_from, six.string_types): volumes_from = ','.join(volumes_from) @@ -958,5 +973,6 @@ def create_container_config( 'MacAddress': mac_address, 'Labels': labels, 'VolumeDriver': volume_driver, - 'StopSignal': stop_signal + 'StopSignal': stop_signal, + 'Tmpfs': tmpfs } diff --git a/docs/api.md b/docs/api.md index 3393e68ef1..193feba8a6 100644 --- a/docs/api.md +++ b/docs/api.md @@ -222,6 +222,7 @@ following format `["PASSWORD=xxx"]` or `{"PASSWORD": "xxx"}`. * volumes (str or list): * volumes_from (str or list): List of container names or Ids to get volumes from. Optionally a single string joining container id's with commas +* tmpfs (str or list): Paths to mount tmpfs filesystems * network_disabled (bool): Disable networking * name (str): A name for the container * entrypoint (str or list): An entrypoint diff --git a/tests/unit/container_test.py b/tests/unit/container_test.py index 6e23f89210..d0fa69346c 100644 --- a/tests/unit/container_test.py +++ b/tests/unit/container_test.py @@ -225,6 +225,28 @@ def test_create_container_with_volume_string(self): self.assertEqual(args[1]['headers'], {'Content-Type': 'application/json'}) + @requires_api_version('1.22') + def test_create_container_with_tmpfs(self): + tmpfs_dest = '/tmpdir' + + self.client.create_container('busybox', ['ls', tmpfs_dest], + tmpfs=tmpfs_dest) + + args = fake_request.call_args + self.assertEqual(args[0][1], + url_prefix + 'containers/create') + self.assertEqual(json.loads(args[1]['data']), + json.loads(''' + {"Tty": false, "Image": "busybox", + "Cmd": ["ls", "/tmpdir"], "AttachStdin": false, + "Tmpfs": {"/tmpdir": ""}, + "AttachStderr": true, + "AttachStdout": true, "OpenStdin": false, + "StdinOnce": false, + "NetworkDisabled": false}''')) + self.assertEqual(args[1]['headers'], + {'Content-Type': 'application/json'}) + def test_create_container_with_ports(self): self.client.create_container('busybox', 'ls', ports=[1111, (2222, 'udp'), (3333,)])