diff options
author | Aanand Prasad <aanand.prasad@gmail.com> | 2015-08-25 14:03:51 +0100 |
---|---|---|
committer | Aanand Prasad <aanand.prasad@gmail.com> | 2015-08-25 14:03:51 +0100 |
commit | d9a149f32711f324ae79813f3485da8fb83e1f53 (patch) | |
tree | 2c971bbacc54e00ef8b59a60c166df64363aa1bb | |
parent | 4d2c15fad15fc9dcb102d273c45277f3b09fecab (diff) | |
parent | 75e3b8bb71253bfa5212415f52417d2e80e0ef49 (diff) | |
download | docker-py-d9a149f32711f324ae79813f3485da8fb83e1f53.tar.gz |
Merge pull request #732 from docker/version-dependent-hostconfig
Version dependent hostconfig
-rw-r--r-- | docker/client.py | 15 | ||||
-rw-r--r-- | docker/utils/utils.py | 12 | ||||
-rw-r--r-- | docs/api.md | 2 | ||||
-rw-r--r-- | docs/hostconfig.md | 7 | ||||
-rw-r--r-- | tests/test.py | 87 | ||||
-rw-r--r-- | tests/utils_test.py | 25 |
6 files changed, 90 insertions, 58 deletions
diff --git a/docker/client.py b/docker/client.py index c639d33..542b8c5 100644 --- a/docker/client.py +++ b/docker/client.py @@ -248,8 +248,8 @@ class Client(clientbase.ClientBase): 'host_config is not supported in API < 1.15' ) - config = utils.create_container_config( - self._version, image, command, hostname, user, detach, stdin_open, + config = self.create_container_config( + image, command, hostname, user, detach, stdin_open, 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, @@ -257,6 +257,9 @@ class Client(clientbase.ClientBase): ) return self.create_container_from_config(config, name) + def create_container_config(self, *args, **kwargs): + return utils.create_container_config(self._version, *args, **kwargs) + def create_container_from_config(self, config, name=None): u = self._url("/containers/create") params = { @@ -265,6 +268,12 @@ class Client(clientbase.ClientBase): res = self._post_json(u, data=config, params=params) return self._result(res, True) + def create_host_config(self, *args, **kwargs): + if not kwargs: + kwargs = {} + kwargs['version'] = self._version + return utils.create_host_config(*args, **kwargs) + @check_resource def diff(self, container): return self._result(self._get(self._url("/containers/{0}/changes". @@ -815,7 +824,7 @@ class Client(clientbase.ClientBase): 'Please use host_config in create_container instead!', DeprecationWarning ) - start_config = utils.create_host_config(**start_config_kwargs) + start_config = self.create_host_config(**start_config_kwargs) url = self._url("/containers/{0}/start".format(container)) res = self._post_json(url, data=start_config) diff --git a/docker/utils/utils.py b/docker/utils/utils.py index 9c4680b..8f69950 100644 --- a/docker/utils/utils.py +++ b/docker/utils/utils.py @@ -27,6 +27,7 @@ from datetime import datetime import requests import six +from .. import constants from .. import errors from .. import tls from .types import Ulimit, LogConfig @@ -395,10 +396,17 @@ def create_host_config( restart_policy=None, cap_add=None, cap_drop=None, devices=None, extra_hosts=None, read_only=None, pid_mode=None, ipc_mode=None, security_opt=None, ulimits=None, log_config=None, mem_limit=None, - memswap_limit=None, cgroup_parent=None + memswap_limit=None, cgroup_parent=None, version=None ): host_config = {} + if not version: + warnings.warn( + 'docker.utils.create_host_config() is deprecated. Please use ' + 'Client.create_host_config() instead.' + ) + version = constants.DEFAULT_DOCKER_API_VERSION + if mem_limit is not None: if isinstance(mem_limit, six.string_types): mem_limit = parse_bytes(mem_limit) @@ -433,7 +441,7 @@ def create_host_config( if network_mode: host_config['NetworkMode'] = network_mode - elif network_mode is None: + elif network_mode is None and compare_version('1.19', version) > 0: host_config['NetworkMode'] = 'default' if restart_policy: diff --git a/docs/api.md b/docs/api.md index 1fdbd1e..4307ea0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -234,7 +234,7 @@ from. Optionally a single string joining container id's with commas 'Warnings': None} ``` -### parse_env_file +### docker.utils.parse_env_file A utility for parsing an environment file. diff --git a/docs/hostconfig.md b/docs/hostconfig.md index c2a4eda..e21148b 100644 --- a/docs/hostconfig.md +++ b/docs/hostconfig.md @@ -6,7 +6,7 @@ The Docker Remote API introduced [support for HostConfig in version 1.15](http:/ ## HostConfig helper -### docker.utils.create_host_config +### Client.create_host_config Creates a HostConfig dictionary to be used with `Client.create_container`. @@ -97,7 +97,8 @@ for example: **Returns** (dict) HostConfig dictionary ```python ->>> from docker.utils import create_host_config ->>> create_host_config(privileged=True, cap_drop=['MKNOD'], volumes_from=['nostalgic_newton']) +>>> from docker import Client +>>> c = Client() +>>> c.create_host_config(privileged=True, cap_drop=['MKNOD'], volumes_from=['nostalgic_newton']) {'CapDrop': ['MKNOD'], 'LxcConf': None, 'Privileged': True, 'VolumesFrom': ['nostalgic_newton'], 'PublishAllPorts': False} ``` diff --git a/tests/test.py b/tests/test.py index 4a8a871..8f08280 100644 --- a/tests/test.py +++ b/tests/test.py @@ -48,7 +48,6 @@ DEFAULT_TIMEOUT_SECONDS = docker.client.constants.DEFAULT_TIMEOUT_SECONDS warnings.simplefilter('error') warnings.filterwarnings('error') -create_host_config = docker.utils.create_host_config def response(status_code=200, content='', headers=None, reason=None, elapsed=0, @@ -495,7 +494,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_cgroup_parent(self): try: self.client.create_container( - 'busybox', 'ls', host_config=create_host_config( + 'busybox', 'ls', host_config=self.client.create_host_config( cgroup_parent='test' ) ) @@ -604,7 +603,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_mem_limit_as_int(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( mem_limit=128.0 ) ) @@ -618,7 +617,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_mem_limit_as_string(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( mem_limit='128' ) ) @@ -632,7 +631,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_mem_limit_as_string_with_k_unit(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( mem_limit='128k' ) ) @@ -646,7 +645,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_mem_limit_as_string_with_m_unit(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( mem_limit='128m' ) ) @@ -661,7 +660,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_mem_limit_as_string_with_g_unit(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( mem_limit='128g' ) ) @@ -676,11 +675,13 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_mem_limit_as_string_with_wrong_value(self): self.assertRaises( - docker.errors.DockerException, create_host_config, mem_limit='128p' + docker.errors.DockerException, + self.client.create_host_config, mem_limit='128p' ) self.assertRaises( - docker.errors.DockerException, create_host_config, mem_limit='1f28' + docker.errors.DockerException, + self.client.create_host_config, mem_limit='1f28' ) def test_start_container(self): @@ -726,7 +727,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_lxc_conf(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( lxc_conf={'lxc.conf.k': 'lxc.conf.value'} ) ) @@ -738,7 +739,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): url_prefix + 'containers/create' ) expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['LxcConf'] = [ {"Value": "lxc.conf.value", "Key": "lxc.conf.k"} ] @@ -756,7 +757,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_lxc_conf_compat(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( lxc_conf=[{'Key': 'lxc.conf.k', 'Value': 'lxc.conf.value'}] ) ) @@ -766,7 +767,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['LxcConf'] = [ {"Value": "lxc.conf.value", "Key": "lxc.conf.k"} ] @@ -784,7 +785,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): mount_dest = '/mnt' mount_origin = '/tmp' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( binds={mount_origin: { "bind": mount_dest, "ro": True @@ -798,7 +799,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:ro"] self.assertEqual(json.loads(args[1]['data']), expected_payload) self.assertEqual(args[1]['headers'], @@ -813,7 +814,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): mount_dest = '/mnt' mount_origin = '/tmp' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( binds={mount_origin: { "bind": mount_dest, "ro": False @@ -827,7 +828,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:rw"] self.assertEqual(json.loads(args[1]['data']), expected_payload) self.assertEqual(args[1]['headers'], @@ -842,7 +843,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): mount_dest = '/mnt' mount_origin = '/tmp' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( binds={mount_origin: { "bind": mount_dest, "mode": "z", @@ -856,7 +857,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Binds'] = ["/tmp:/mnt:z"] self.assertEqual(json.loads(args[1]['data']), expected_payload) self.assertEqual(args[1]['headers'], @@ -871,7 +872,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): mount_dest = '/mnt' mount_origin = '/tmp' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( binds={mount_origin: { "bind": mount_dest, "mode": "z", @@ -887,7 +888,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_binds_list(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( binds=[ "/tmp:/mnt/1:ro", "/tmp:/mnt/2", @@ -901,7 +902,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Binds'] = [ "/tmp:/mnt/1:ro", "/tmp:/mnt/2", @@ -918,7 +919,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): self.maxDiff = None try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( port_bindings={ 1111: None, 2222: 2222, @@ -987,7 +988,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): link_path = 'path' alias = 'alias' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( links={link_path: alias} ) ) @@ -999,7 +1000,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): args[0][0], url_prefix + 'containers/create' ) expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Links'] = ['path:alias'] self.assertEqual(json.loads(args[1]['data']), expected_payload) @@ -1012,7 +1013,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): link_path = 'path' alias = 'alias' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( links={ link_path + '1': alias + '1', link_path + '2': alias + '2' @@ -1025,7 +1026,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Links'] = [ 'path1:alias1', 'path2:alias2' ] @@ -1039,7 +1040,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): link_path = 'path' alias = 'alias' self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( links=[(link_path, alias)] ) ) @@ -1049,7 +1050,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Links'] = ['path:alias'] self.assertEqual(json.loads(args[1]['data']), expected_payload) @@ -1061,13 +1062,13 @@ class DockerClientTest(Cleanup, base.BaseTestCase): try: self.client.create_container( 'busybox', 'true', - host_config=create_host_config(privileged=True) + host_config=self.client.create_host_config(privileged=True) ) except Exception as e: self.fail('Command should not raise exception: {0}'.format(e)) expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Privileged'] = True args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') @@ -1306,7 +1307,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_restart_policy(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( restart_policy={ "Name": "always", "MaximumRetryCount": 0 @@ -1319,7 +1320,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['RestartPolicy'] = { "MaximumRetryCount": 0, "Name": "always" } @@ -1336,14 +1337,14 @@ class DockerClientTest(Cleanup, base.BaseTestCase): try: self.client.create_container( 'busybox', 'true', - host_config=create_host_config(cap_add=['MKNOD']) + host_config=self.client.create_host_config(cap_add=['MKNOD']) ) except Exception as e: self.fail('Command should not raise exception: {0}'.format(e)) args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['CapAdd'] = ['MKNOD'] self.assertEqual(json.loads(args[1]['data']), expected_payload) self.assertEqual( @@ -1357,14 +1358,14 @@ class DockerClientTest(Cleanup, base.BaseTestCase): try: self.client.create_container( 'busybox', 'true', - host_config=create_host_config(cap_drop=['MKNOD']) + host_config=self.client.create_host_config(cap_drop=['MKNOD']) ) except Exception as e: self.fail('Command should not raise exception: {0}'.format(e)) args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['CapDrop'] = ['MKNOD'] self.assertEqual(json.loads(args[1]['data']), expected_payload) self.assertEqual( @@ -1377,7 +1378,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_container_with_devices(self): try: self.client.create_container( - 'busybox', 'true', host_config=create_host_config( + 'busybox', 'true', host_config=self.client.create_host_config( devices=['/dev/sda:/dev/xvda:rwm', '/dev/sdb:/dev/xvdb', '/dev/sdc'] @@ -1388,7 +1389,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): args = fake_request.call_args self.assertEqual(args[0][0], url_prefix + 'containers/create') expected_payload = self.base_create_payload() - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Devices'] = [ {'CgroupPermissions': 'rwm', 'PathInContainer': '/dev/xvda', @@ -1462,7 +1463,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): volume_name = 'name' self.client.create_container( 'busybox', 'true', - host_config=create_host_config( + host_config=self.client.create_host_config( binds={volume_name: { "bind": mount_dest, "ro": False @@ -1477,7 +1478,7 @@ class DockerClientTest(Cleanup, base.BaseTestCase): 'containers/create') expected_payload = self.base_create_payload() expected_payload['VolumeDriver'] = 'foodriver' - expected_payload['HostConfig'] = create_host_config() + expected_payload['HostConfig'] = self.client.create_host_config() expected_payload['HostConfig']['Binds'] = ["name:/mnt:rw"] self.assertEqual(json.loads(args[1]['data']), expected_payload) self.assertEqual(args[1]['headers'], @@ -2536,12 +2537,12 @@ class DockerClientTest(Cleanup, base.BaseTestCase): def test_create_host_config_secopt(self): security_opt = ['apparmor:test_profile'] - result = create_host_config(security_opt=security_opt) + result = self.client.create_host_config(security_opt=security_opt) self.assertIn('SecurityOpt', result) self.assertEqual(result['SecurityOpt'], security_opt) self.assertRaises( - docker.errors.DockerException, create_host_config, + docker.errors.DockerException, self.client.create_host_config, security_opt='wrong' ) diff --git a/tests/utils_test.py b/tests/utils_test.py index 5b052e4..91d676f 100644 --- a/tests/utils_test.py +++ b/tests/utils_test.py @@ -4,6 +4,7 @@ import unittest import tempfile from docker.client import Client +from docker.constants import DEFAULT_DOCKER_API_VERSION from docker.errors import DockerException from docker.utils import ( parse_repository_tag, parse_host, convert_filters, kwargs_from_env, @@ -144,12 +145,16 @@ class UtilsTest(base.BaseTestCase): self.assertEqual(convert_filters(filters), expected) def test_create_empty_host_config(self): - empty_config = create_host_config(network_mode='') + empty_config = create_host_config( + network_mode='', version=DEFAULT_DOCKER_API_VERSION + ) self.assertEqual(empty_config, {}) def test_create_host_config_dict_ulimit(self): ulimit_dct = {'name': 'nofile', 'soft': 8096} - config = create_host_config(ulimits=[ulimit_dct]) + config = create_host_config( + ulimits=[ulimit_dct], version=DEFAULT_DOCKER_API_VERSION + ) self.assertIn('Ulimits', config) self.assertEqual(len(config['Ulimits']), 1) ulimit_obj = config['Ulimits'][0] @@ -160,7 +165,9 @@ class UtilsTest(base.BaseTestCase): def test_create_host_config_dict_ulimit_capitals(self): ulimit_dct = {'Name': 'nofile', 'Soft': 8096, 'Hard': 8096 * 4} - config = create_host_config(ulimits=[ulimit_dct]) + config = create_host_config( + ulimits=[ulimit_dct], version=DEFAULT_DOCKER_API_VERSION + ) self.assertIn('Ulimits', config) self.assertEqual(len(config['Ulimits']), 1) ulimit_obj = config['Ulimits'][0] @@ -172,7 +179,9 @@ class UtilsTest(base.BaseTestCase): def test_create_host_config_obj_ulimit(self): ulimit_dct = Ulimit(name='nofile', soft=8096) - config = create_host_config(ulimits=[ulimit_dct]) + config = create_host_config( + ulimits=[ulimit_dct], version=DEFAULT_DOCKER_API_VERSION + ) self.assertIn('Ulimits', config) self.assertEqual(len(config['Ulimits']), 1) ulimit_obj = config['Ulimits'][0] @@ -186,14 +195,18 @@ class UtilsTest(base.BaseTestCase): def test_create_host_config_dict_logconfig(self): dct = {'type': LogConfig.types.SYSLOG, 'config': {'key1': 'val1'}} - config = create_host_config(log_config=dct) + config = create_host_config( + log_config=dct, version=DEFAULT_DOCKER_API_VERSION + ) self.assertIn('LogConfig', config) self.assertTrue(isinstance(config['LogConfig'], LogConfig)) self.assertEqual(dct['type'], config['LogConfig'].type) def test_create_host_config_obj_logconfig(self): obj = LogConfig(type=LogConfig.types.SYSLOG, config={'key1': 'val1'}) - config = create_host_config(log_config=obj) + config = create_host_config( + log_config=obj, version=DEFAULT_DOCKER_API_VERSION + ) self.assertIn('LogConfig', config) self.assertTrue(isinstance(config['LogConfig'], LogConfig)) self.assertEqual(obj, config['LogConfig']) |