diff options
author | Joffrey F <f.joffrey@gmail.com> | 2015-05-08 14:32:42 -0700 |
---|---|---|
committer | Joffrey F <f.joffrey@gmail.com> | 2015-05-08 14:32:42 -0700 |
commit | 329662c53ed13254449ef55742d2e8d577e0dd97 (patch) | |
tree | 07c6ce0593ec7887080db95629ae4119d47fd6e1 | |
parent | 8261a9175ec84a5e18c2b1422dc2269ffa8dc245 (diff) | |
parent | 5af442fb9bfa72d6f928490d2faae414e06af7d5 (diff) | |
download | docker-py-329662c53ed13254449ef55742d2e8d577e0dd97.tar.gz |
Merge pull request #593 from docker/deprecate_start_hostconfig
Deprecate start hostconfig
-rw-r--r-- | docker/client.py | 6 | ||||
-rw-r--r-- | docs/api.md | 83 | ||||
-rw-r--r-- | docs/host-devices.md | 9 | ||||
-rw-r--r-- | docs/hostconfig.md | 4 | ||||
-rw-r--r-- | docs/port-bindings.md | 31 | ||||
-rw-r--r-- | docs/volumes.md | 24 | ||||
-rw-r--r-- | tests/integration_test.py | 282 | ||||
-rw-r--r-- | tests/test.py | 405 |
8 files changed, 232 insertions, 612 deletions
diff --git a/docker/client.py b/docker/client.py index 2d1349c..4775ee7 100644 --- a/docker/client.py +++ b/docker/client.py @@ -1059,6 +1059,12 @@ class Client(requests.Session): url = self._url("/containers/{0}/start".format(container)) if not start_config: start_config = None + elif utils.compare_version('1.15', self._version) > 0: + warnings.warn( + 'Passing host config parameters in start() is deprecated. ' + 'Please use host_config in create_container instead!', + DeprecationWarning + ) res = self._post_json(url, data=start_config) self._raise_for_status(res) diff --git a/docs/api.md b/docs/api.md index eaa08a1..26dfe60 100644 --- a/docs/api.md +++ b/docs/api.md @@ -188,8 +188,7 @@ character, bytes are assumed as an intended unit. `volumes_from` and `dns` arguments raise [TypeError]( https://docs.python.org/3.4/library/exceptions.html#TypeError) exception if they are used against v1.10 and above of the Docker remote API. Those -arguments should be passed to `start()` instead, or as part of the `host_config` -dictionary. +arguments should be passed as part of the `host_config` dictionary. **Params**: @@ -715,83 +714,9 @@ Identical to the `docker search` command. Similar to the `docker start` command, but doesn't support attach options. Use `.logs()` to recover `stdout`/`stderr`. -`binds` allows to bind a directory in the host to the container. See [Using -volumes](volumes.md) for more information. - -`port_bindings` exposes container ports to the host. -See [Port bindings](port-bindings.md) for more information. - -`lxc_conf` allows to pass LXC configuration options using a dictionary. - -`privileged` starts the container in privileged mode. - -[Links](http://docs.docker.io/en/latest/use/working_with_links_names/) can be -specified with the `links` argument. They can either be specified as a -dictionary mapping name to alias or as a list of `(name, alias)` tuples. - -`dns` and `volumes_from` are only available if they are used with version v1.10 -of docker remote API. Otherwise they are ignored. - -`network_mode` is available since v1.11 and sets the Network mode for the -container ('bridge': creates a new network stack for the container on the -Docker bridge, 'none': no networking for this container, 'container:[name|id]': -reuses another container network stack), 'host': use the host network stack -inside the container. - -`restart_policy` is available since v1.2.0 and sets the RestartPolicy for how a -container should or should not be restarted on exit. By default the policy is -set to no meaning do not restart the container when it exits. The user may -specify the restart policy as a dictionary for example: -```python -{ - "MaximumRetryCount": 0, - "Name": "always" -} -``` - -For always restarting the container on exit or can specify to restart the -container to restart on failure and can limit number of restarts. For example: -```python -{ - "MaximumRetryCount": 5, - "Name": "on-failure" -} -``` - -`cap_add` and `cap_drop` are available since v1.2.0 and can be used to add or -drop certain capabilities. The user may specify the capabilities as an array -for example: -```python -[ - "SYS_ADMIN", - "MKNOD" -] -``` - -**Params**: - -* container (str): The container to start -* binds: Volumes to bind -* port_bindings (dict): Port bindings. See note above -* lxc_conf (dict): LXC config -* publish_all_ports (bool): Whether to publish all ports to the host -* links (dict or list of tuples): See note above -* privileged (bool): Give extended privileges to this container -* dns (list): Set custom DNS servers -* dns_search (list): DNS search domains -* 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 -* network_mode (str): One of `['bridge', None, 'container:<name|id>', -'host']` -* restart_policy (dict): See note above. "Name" param must be one of -`['on-failure', 'always']` -* cap_add (list of str): See note above -* cap_drop (list of str): See note above -* extra_hosts (dict): custom host-to-IP mappings (host:ip) -* pid_mode (str): if set to "host", use the host PID namespace inside the - container -* security_opt (list): A list of string values to customize labels for MLS systems, such as SELinux. -* ulimits (list): A list of dicts or `docker.utils.Ulimit` objects. +**Deprecation warning:** For API version > 1.15, it is highly recommended to + provide host config options in the + [`host_config` parameter of `create_container`](#create_container) ```python >>> from docker import Client diff --git a/docs/host-devices.md b/docs/host-devices.md index ae1d32b..f1ee3e1 100644 --- a/docs/host-devices.md +++ b/docs/host-devices.md @@ -1,10 +1,15 @@ # Access to devices on the host If you need to directly expose some host devices to a container, you can use -the devices parameter in the `Client.start` method as shown below +the devices parameter in the `host_config` param in `Client.create_container` +as shown below: ```python -c.start(container_id, devices=['/dev/sda:/dev/xvda:rwm']) +c.create_container( + 'busybox', 'true', host_config=docker.utils.create_host_config(devices=[ + '/dev/sda:/dev/xvda:rwm' + ]) +) ``` Each string is a single mapping using the colon (':') as the separator. So the diff --git a/docs/hostconfig.md b/docs/hostconfig.md index 99ffe1c..c9f9464 100644 --- a/docs/hostconfig.md +++ b/docs/hostconfig.md @@ -1,6 +1,8 @@ # HostConfig object -The Docker Remote API introduced [support for HostConfig in version 1.15](http://docs.docker.com/reference/api/docker_remote_api_v1.15/#create-a-container). This object contains all the parameters you can pass to `Client.start`. +The Docker Remote API introduced [support for HostConfig in version 1.15](http://docs.docker.com/reference/api/docker_remote_api_v1.15/#create-a-container). This object contains all the parameters you could previously pass to `Client.start`. +*It is highly recommended that users pass the HostConfig in the `host_config`* +*param of `Client.create_container` instead of `Client.start`* ## HostConfig helper diff --git a/docs/port-bindings.md b/docs/port-bindings.md index 90523f2..7456b86 100644 --- a/docs/port-bindings.md +++ b/docs/port-bindings.md @@ -1,38 +1,39 @@ # Port bindings Port bindings is done in two parts. Firstly, by providing a list of ports to open inside the container in the `Client().create_container()` method. +Bindings are declared in the `host_config` parameter. ```python -container_id = c.create_container('busybox', 'ls', ports=[1111, 2222]) +container_id = c.create_container( + 'busybox', 'ls', ports=[1111, 2222], + host_config=docker.utils.create_host_config(port_bindings={ + 1111: 4567, + 2222: None + }) +) ``` -Bindings are then declared in the `Client.start` method. - -```python -c.start(container_id, port_bindings={1111: 4567, 2222: None}) -``` You can limit the host address on which the port will be exposed like such: ```python -c.start(container_id, port_bindings={1111: ('127.0.0.1', 4567)}) +docker.utils.create_host_config(port_bindings={1111: ('127.0.0.1', 4567)}) ``` Or without host port assignment: ```python -c.start(container_id, port_bindings={1111: ('127.0.0.1',)}) +docker.utils.create_host_config(port_bindings={1111: ('127.0.0.1',)}) ``` -If you wish to use UDP instead of TCP (default), you need to declare it -like such in both the `create_container()` and `start()` calls: +If you wish to use UDP instead of TCP (default), you need to declare ports +as such in both the config and host config: ```python container_id = c.create_container( - 'busybox', - 'ls', - ports=[(1111, 'udp'), 2222] + 'busybox', 'ls', ports=[(1111, 'udp'), 2222], + host_config=docker.utils.create_host_config(port_bindings={ + '1111/udp': 4567, 2222: None + }) ) -c.start(container_id, port_bindings={'1111/udp': 4567, 2222: None}) ``` - diff --git a/docs/volumes.md b/docs/volumes.md index 4441b82..de28214 100644 --- a/docs/volumes.md +++ b/docs/volumes.md @@ -1,25 +1,21 @@ # Using volumes -Volume declaration is done in two parts. First, you have to provide -a list of mountpoints to the `Client().create_container()` method. +Volume declaration is done in two parts. Provide a list of mountpoints to +the `Client().create_container()` method, and declare mappings in the +`host_config` section. ```python -container_id = c.create_container('busybox', 'ls', volumes=['/mnt/vol1', '/mnt/vol2']) -``` - -Volume mappings are then declared inside the `Client.start` method like this: - -```python -c.start(container_id, binds={ - '/home/user1/': - { +container_id = c.create_container( + 'busybox', 'ls', volumes=['/mnt/vol1', '/mnt/vol2'], + host_config=docker.utils.create_host_config(binds={ + '/home/user1/': { 'bind': '/mnt/vol2', 'ro': False }, - '/var/www': - { + '/var/www': { 'bind': '/mnt/vol1', 'ro': True } -}) + }) +) ``` diff --git a/tests/integration_test.py b/tests/integration_test.py index 0a56912..2660900 100644 --- a/tests/integration_test.py +++ b/tests/integration_test.py @@ -242,113 +242,6 @@ class TestCreateContainerWithRoBinds(BaseTestCase): self.assertFalse(inspect_data['VolumesRW'][mount_dest]) -class TestStartContainerWithBinds(BaseTestCase): - def runTest(self): - mount_dest = '/mnt' - mount_origin = tempfile.mkdtemp() - self.tmp_folders.append(mount_origin) - - filename = 'shared.txt' - shared_file = os.path.join(mount_origin, filename) - binds = { - mount_origin: { - 'bind': mount_dest, - 'ro': False, - }, - } - - with open(shared_file, 'w'): - container = self.client.create_container( - 'busybox', ['ls', mount_dest], volumes={mount_dest: {}} - ) - container_id = container['Id'] - self.client.start(container_id, binds=binds) - self.tmp_containers.append(container_id) - exitcode = self.client.wait(container_id) - self.assertEqual(exitcode, 0) - logs = self.client.logs(container_id) - - os.unlink(shared_file) - if six.PY3: - logs = logs.decode('utf-8') - self.assertIn(filename, logs) - inspect_data = self.client.inspect_container(container_id) - self.assertIn('Volumes', inspect_data) - self.assertIn(mount_dest, inspect_data['Volumes']) - self.assertEqual(mount_origin, inspect_data['Volumes'][mount_dest]) - self.assertIn(mount_dest, inspect_data['VolumesRW']) - self.assertTrue(inspect_data['VolumesRW'][mount_dest]) - - -class TestStartContainerWithRoBinds(BaseTestCase): - def runTest(self): - mount_dest = '/mnt' - mount_origin = tempfile.mkdtemp() - self.tmp_folders.append(mount_origin) - - filename = 'shared.txt' - shared_file = os.path.join(mount_origin, filename) - binds = { - mount_origin: { - 'bind': mount_dest, - 'ro': True, - }, - } - - with open(shared_file, 'w'): - container = self.client.create_container( - 'busybox', ['ls', mount_dest], volumes={mount_dest: {}} - ) - container_id = container['Id'] - self.client.start(container_id, binds=binds) - self.tmp_containers.append(container_id) - exitcode = self.client.wait(container_id) - self.assertEqual(exitcode, 0) - logs = self.client.logs(container_id) - - os.unlink(shared_file) - if six.PY3: - logs = logs.decode('utf-8') - self.assertIn(filename, logs) - - inspect_data = self.client.inspect_container(container_id) - self.assertIn('Volumes', inspect_data) - self.assertIn(mount_dest, inspect_data['Volumes']) - self.assertEqual(mount_origin, inspect_data['Volumes'][mount_dest]) - self.assertIn('VolumesRW', inspect_data) - self.assertIn(mount_dest, inspect_data['VolumesRW']) - self.assertFalse(inspect_data['VolumesRW'][mount_dest]) - - -class TestStartContainerWithFileBind(BaseTestCase): - def runTest(self): - mount_dest = '/myfile/myfile' - mount_origin = tempfile.mktemp() - try: - binds = { - mount_origin: { - 'bind': mount_dest, - 'ro': True - }, - } - - with open(mount_origin, 'w') as f: - f.write('sakuya izayoi') - - container = self.client.create_container( - 'busybox', ['cat', mount_dest], volumes={mount_dest: {}} - ) - self.client.start(container, binds=binds) - exitcode = self.client.wait(container) - self.assertEqual(exitcode, 0) - logs = self.client.logs(container) - if six.PY3: - logs = logs.decode('utf-8') - self.assertIn('sakuya izayoi', logs) - finally: - os.unlink(mount_origin) - - class TestCreateContainerWithLogConfig(BaseTestCase): def runTest(self): config = docker.utils.LogConfig( @@ -388,21 +281,6 @@ class TestCreateContainerReadOnlyFs(BaseTestCase): self.assertNotEqual(res, 0) -@unittest.skipIf(not EXEC_DRIVER_IS_NATIVE, 'Exec driver not native') -class TestStartContainerReadOnlyFs(BaseTestCase): - def runTest(self): - # Presumably a bug in 1.5.0 - # https://github.com/docker/docker/issues/10695 - ctnr = self.client.create_container( - 'busybox', ['mkdir', '/shrine'], - ) - self.assertIn('Id', ctnr) - self.tmp_containers.append(ctnr['Id']) - self.client.start(ctnr, read_only=True) - # res = self.client.wait(ctnr) - # self.assertNotEqual(res, 0) - - class TestCreateContainerWithName(BaseTestCase): def runTest(self): res = self.client.create_container('busybox', 'true', name='foobar') @@ -490,29 +368,6 @@ class TestCreateContainerPrivileged(BaseTestCase): self.assertEqual(inspect['Config']['Privileged'], True) -class TestStartContainerPrivileged(BaseTestCase): - def runTest(self): - res = self.client.create_container('busybox', 'true') - self.assertIn('Id', res) - self.tmp_containers.append(res['Id']) - self.client.start(res['Id'], privileged=True) - inspect = self.client.inspect_container(res['Id']) - self.assertIn('Config', inspect) - self.assertIn('Id', inspect) - self.assertTrue(inspect['Id'].startswith(res['Id'])) - self.assertIn('Image', inspect) - self.assertIn('State', inspect) - self.assertIn('Running', inspect['State']) - if not inspect['State']['Running']: - self.assertIn('ExitCode', inspect['State']) - self.assertEqual(inspect['State']['ExitCode'], 0) - # Since Nov 2013, the Privileged flag is no longer part of the - # container's config exposed via the API (safety concerns?). - # - if 'Privileged' in inspect['Config']: - self.assertEqual(inspect['Config']['Privileged'], True) - - class TestWait(BaseTestCase): def runTest(self): res = self.client.create_container('busybox', ['sleep', '3']) @@ -754,34 +609,6 @@ class TestPort(BaseTestCase): self.client.kill(id) -class TestStartWithPortBindings(BaseTestCase): - def runTest(self): - - port_bindings = { - '1111': ('127.0.0.1', '4567'), - '2222': ('127.0.0.1', '4568') - } - - container = self.client.create_container( - 'busybox', ['sleep', '60'], ports=list(port_bindings.keys()) - ) - id = container['Id'] - - self.client.start(container, port_bindings=port_bindings) - - # Call the port function on each biding and compare expected vs actual - for port in port_bindings: - actual_bindings = self.client.port(container, port) - port_binding = actual_bindings.pop() - - ip, host_port = port_binding['HostIp'], port_binding['HostPort'] - - self.assertEqual(ip, port_bindings[port][0]) - self.assertEqual(host_port, port_bindings[port][1]) - - self.client.kill(id) - - class TestMacAddress(BaseTestCase): def runTest(self): mac_address_expected = "02:42:ac:11:00:0a" @@ -949,101 +776,6 @@ class TestCreateContainerWithLinks(BaseTestCase): self.assertIn('{0}_ENV_FOO=1'.format(link_env_prefix2), logs) -class TestStartContainerWithVolumesFrom(BaseTestCase): - def runTest(self): - vol_names = ['foobar_vol0', 'foobar_vol1'] - - res0 = self.client.create_container( - 'busybox', 'true', - name=vol_names[0]) - container1_id = res0['Id'] - self.tmp_containers.append(container1_id) - self.client.start(container1_id) - - res1 = self.client.create_container( - 'busybox', 'true', - name=vol_names[1]) - container2_id = res1['Id'] - self.tmp_containers.append(container2_id) - self.client.start(container2_id) - with self.assertRaises(docker.errors.DockerException): - res2 = self.client.create_container( - 'busybox', 'cat', - detach=True, stdin_open=True, - volumes_from=vol_names) - res2 = self.client.create_container( - 'busybox', 'cat', - detach=True, stdin_open=True) - container3_id = res2['Id'] - self.tmp_containers.append(container3_id) - self.client.start(container3_id, volumes_from=vol_names) - - info = self.client.inspect_container(res2['Id']) - self.assertCountEqual(info['HostConfig']['VolumesFrom'], vol_names) - - -class TestStartContainerWithUlimits(BaseTestCase): - def runTest(self): - ulimit = docker.utils.Ulimit(name='nofile', soft=4096, hard=4096) - - res0 = self.client.create_container('busybox', 'true') - container1_id = res0['Id'] - self.tmp_containers.append(container1_id) - self.client.start(container1_id, ulimits=[ulimit]) - - info = self.client.inspect_container(container1_id) - self.assertCountEqual(info['HostConfig']['Ulimits'], [ulimit]) - - -class TestStartContainerWithLinks(BaseTestCase): - def runTest(self): - res0 = self.client.create_container( - 'busybox', 'cat', - detach=True, stdin_open=True, - environment={'FOO': '1'}) - - container1_id = res0['Id'] - self.tmp_containers.append(container1_id) - - self.client.start(container1_id) - - res1 = self.client.create_container( - 'busybox', 'cat', - detach=True, stdin_open=True, - environment={'FOO': '1'}) - - container2_id = res1['Id'] - self.tmp_containers.append(container2_id) - - self.client.start(container2_id) - - # we don't want the first / - link_path1 = self.client.inspect_container(container1_id)['Name'][1:] - link_alias1 = 'mylink1' - link_env_prefix1 = link_alias1.upper() - - link_path2 = self.client.inspect_container(container2_id)['Name'][1:] - link_alias2 = 'mylink2' - link_env_prefix2 = link_alias2.upper() - - res2 = self.client.create_container('busybox', 'env') - container3_id = res2['Id'] - self.tmp_containers.append(container3_id) - self.client.start( - container3_id, - links={link_path1: link_alias1, link_path2: link_alias2} - ) - self.assertEqual(self.client.wait(container3_id), 0) - - logs = self.client.logs(container3_id) - if six.PY3: - logs = logs.decode('utf-8') - self.assertIn('{0}_NAME='.format(link_env_prefix1), logs) - self.assertIn('{0}_ENV_FOO=1'.format(link_env_prefix1), logs) - self.assertIn('{0}_NAME='.format(link_env_prefix2), logs) - self.assertIn('{0}_ENV_FOO=1'.format(link_env_prefix2), logs) - - class TestRestartingContainer(BaseTestCase): def runTest(self): container = self.client.create_container( @@ -1190,20 +922,6 @@ class TestCreateContainerWithHostPidMode(BaseTestCase): self.assertEqual(host_config['PidMode'], 'host') -class TestStartContainerWithHostPidMode(BaseTestCase): - def runTest(self): - ctnr = self.client.create_container( - 'busybox', 'true' - ) - self.assertIn('Id', ctnr) - self.tmp_containers.append(ctnr['Id']) - self.client.start(ctnr, pid_mode='host') - inspect = self.client.inspect_container(ctnr) - self.assertIn('HostConfig', inspect) - host_config = inspect['HostConfig'] - self.assertIn('PidMode', host_config) - self.assertEqual(host_config['PidMode'], 'host') - ################# # LINKS TESTS # ################# diff --git a/tests/test.py b/tests/test.py index 17a2e6b..9b90017 100644 --- a/tests/test.py +++ b/tests/test.py @@ -47,6 +47,7 @@ except ImportError: DEFAULT_TIMEOUT_SECONDS = docker.client.constants.DEFAULT_TIMEOUT_SECONDS warnings.simplefilter('error') +warnings.filterwarnings('error') create_host_config = docker.utils.create_host_config @@ -973,244 +974,210 @@ class DockerClientTest(Cleanup, base.BaseTestCase): ) def test_start_container_with_lxc_conf(self): - try: - self.client.start( - fake_api.FAKE_CONTAINER_ID, - lxc_conf={'lxc.conf.k': 'lxc.conf.value'} - ) - 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/3cc2351ab11b/start' - ) - self.assertEqual( - json.loads(args[1]['data']), - {"LxcConf": [{"Value": "lxc.conf.value", "Key": "lxc.conf.k"}]} - ) - self.assertEqual( - args[1]['headers'], - {'Content-Type': 'application/json'} - ) - self.assertEqual( - args[1]['timeout'], - DEFAULT_TIMEOUT_SECONDS - ) + if six.PY2: + try: + self.client.start( + fake_api.FAKE_CONTAINER_ID, + lxc_conf={'lxc.conf.k': 'lxc.conf.value'} + ) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start( + fake_api.FAKE_CONTAINER_ID, + lxc_conf={'lxc.conf.k': 'lxc.conf.value'} + ) def test_start_container_with_lxc_conf_compat(self): - try: - self.client.start( - fake_api.FAKE_CONTAINER_ID, - lxc_conf=[{'Key': 'lxc.conf.k', 'Value': 'lxc.conf.value'}] - ) - 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/3cc2351ab11b/start') - self.assertEqual( - json.loads(args[1]['data']), - {"LxcConf": [{"Key": "lxc.conf.k", "Value": "lxc.conf.value"}]} - ) - self.assertEqual(args[1]['headers'], - {'Content-Type': 'application/json'}) - self.assertEqual( - args[1]['timeout'], - DEFAULT_TIMEOUT_SECONDS - ) + if six.PY2: + try: + self.client.start( + fake_api.FAKE_CONTAINER_ID, + lxc_conf=[{'Key': 'lxc.conf.k', 'Value': 'lxc.conf.value'}] + ) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start( + fake_api.FAKE_CONTAINER_ID, + lxc_conf=[{'Key': 'lxc.conf.k', 'Value': 'lxc.conf.value'}] + ) def test_start_container_with_binds_ro(self): - try: - mount_dest = '/mnt' - mount_origin = '/tmp' - self.client.start(fake_api.FAKE_CONTAINER_ID, - binds={mount_origin: { - "bind": mount_dest, - "ro": True - }}) - 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/3cc2351ab11b/start') - self.assertEqual( - json.loads(args[1]['data']), {"Binds": ["/tmp:/mnt:ro"]} - ) - self.assertEqual(args[1]['headers'], - {'Content-Type': 'application/json'}) - self.assertEqual( - args[1]['timeout'], - DEFAULT_TIMEOUT_SECONDS) + mount_dest = '/mnt' + mount_origin = '/tmp' + + if six.PY2: + try: + self.client.start( + fake_api.FAKE_CONTAINER_ID, binds={ + mount_origin: { + "bind": mount_dest, + "ro": True + } + } + ) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start( + fake_api.FAKE_CONTAINER_ID, binds={ + mount_origin: { + "bind": mount_dest, + "ro": True + } + } + ) def test_start_container_with_binds_rw(self): - try: - mount_dest = '/mnt' - mount_origin = '/tmp' - self.client.start(fake_api.FAKE_CONTAINER_ID, - binds={mount_origin: { - "bind": mount_dest, "ro": False}}) - 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/3cc2351ab11b/start') - self.assertEqual( - json.loads(args[1]['data']), {"Binds": ["/tmp:/mnt:rw"]} - ) - self.assertEqual(args[1]['headers'], - {'Content-Type': 'application/json'}) - self.assertEqual( - args[1]['timeout'], - DEFAULT_TIMEOUT_SECONDS - ) + mount_dest = '/mnt' + mount_origin = '/tmp' + if six.PY2: + try: + self.client.start( + fake_api.FAKE_CONTAINER_ID, binds={ + mount_origin: {"bind": mount_dest, "ro": False} + } + ) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start( + fake_api.FAKE_CONTAINER_ID, binds={ + mount_origin: {"bind": mount_dest, "ro": False} + } + ) def test_start_container_with_port_binds(self): self.maxDiff = None - try: - self.client.start(fake_api.FAKE_CONTAINER_ID, port_bindings={ - 1111: None, - 2222: 2222, - '3333/udp': (3333,), - 4444: ('127.0.0.1',), - 5555: ('127.0.0.1', 5555), - 6666: [('127.0.0.1',), ('192.168.0.1',)] - }) - 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/3cc2351ab11b/start') - data = json.loads(args[1]['data']) - self.assertTrue('1111/tcp' in data['PortBindings']) - self.assertTrue('2222/tcp' in data['PortBindings']) - self.assertTrue('3333/udp' in data['PortBindings']) - self.assertTrue('4444/tcp' in data['PortBindings']) - self.assertTrue('5555/tcp' in data['PortBindings']) - self.assertTrue('6666/tcp' in data['PortBindings']) - self.assertEqual( - [{"HostPort": "", "HostIp": ""}], - data['PortBindings']['1111/tcp'] - ) - self.assertEqual( - [{"HostPort": "2222", "HostIp": ""}], - data['PortBindings']['2222/tcp'] - ) - self.assertEqual( - [{"HostPort": "3333", "HostIp": ""}], - data['PortBindings']['3333/udp'] - ) - self.assertEqual( - [{"HostPort": "", "HostIp": "127.0.0.1"}], - data['PortBindings']['4444/tcp'] - ) - self.assertEqual( - [{"HostPort": "5555", "HostIp": "127.0.0.1"}], - data['PortBindings']['5555/tcp'] - ) - self.assertEqual(len(data['PortBindings']['6666/tcp']), 2) - self.assertEqual(args[1]['headers'], - {'Content-Type': 'application/json'}) - self.assertEqual( - args[1]['timeout'], - DEFAULT_TIMEOUT_SECONDS - ) + if six.PY2: + try: + self.client.start(fake_api.FAKE_CONTAINER_ID, port_bindings={ + 1111: None, + 2222: 2222, + '3333/udp': (3333,), + 4444: ('127.0.0.1',), + 5555: ('127.0.0.1', 5555), + 6666: [('127.0.0.1',), ('192.168.0.1',)] + }) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start(fake_api.FAKE_CONTAINER_ID, port_bindings={ + 1111: None, + 2222: 2222, + '3333/udp': (3333,), + 4444: ('127.0.0.1',), + 5555: ('127.0.0.1', 5555), + 6666: [('127.0.0.1',), ('192.168.0.1',)] + }) def test_start_container_with_links(self): # one link - try: - link_path = 'path' - alias = 'alias' - self.client.start(fake_api.FAKE_CONTAINER_ID, - links={link_path: alias}) - 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/3cc2351ab11b/start' - ) - self.assertEqual( - json.loads(args[1]['data']), {"Links": ["path:alias"]} - ) - self.assertEqual( - args[1]['headers'], - {'Content-Type': 'application/json'} - ) + link_path = 'path' + alias = 'alias' + + if six.PY2: + try: + self.client.start(fake_api.FAKE_CONTAINER_ID, + links={link_path: alias}) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start( + fake_api.FAKE_CONTAINER_ID, links={link_path: alias} + ) def test_start_container_with_multiple_links(self): - try: - link_path = 'path' - alias = 'alias' - self.client.start( - fake_api.FAKE_CONTAINER_ID, - links={ - link_path + '1': alias + '1', - link_path + '2': alias + '2' - } - ) - 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/3cc2351ab11b/start' - ) - self.assertEqual( - json.loads(args[1]['data']), - {"Links": ["path1:alias1", "path2:alias2"]} - ) - self.assertEqual( - args[1]['headers'], - {'Content-Type': 'application/json'} - ) + link_path = 'path' + alias = 'alias' + if six.PY2: + try: + self.client.start( + fake_api.FAKE_CONTAINER_ID, + links={ + link_path + '1': alias + '1', + link_path + '2': alias + '2' + } + ) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start( + fake_api.FAKE_CONTAINER_ID, + links={ + link_path + '1': alias + '1', + link_path + '2': alias + '2' + } + ) def test_start_container_with_links_as_list_of_tuples(self): # one link - try: - link_path = 'path' - alias = 'alias' - self.client.start(fake_api.FAKE_CONTAINER_ID, - links=[(link_path, alias)]) - 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/3cc2351ab11b/start' - ) - self.assertEqual( - json.loads(args[1]['data']), {"Links": ["path:alias"]} - ) - self.assertEqual( - args[1]['headers'], {'Content-Type': 'application/json'} - ) + link_path = 'path' + alias = 'alias' + if six.PY2: + try: + self.client.start(fake_api.FAKE_CONTAINER_ID, + links=[(link_path, alias)]) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start(fake_api.FAKE_CONTAINER_ID, + links=[(link_path, alias)]) def test_start_container_privileged(self): - try: - self.client.start(fake_api.FAKE_CONTAINER_ID, privileged=True) - 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/3cc2351ab11b/start' - ) - self.assertEqual(json.loads(args[1]['data']), {"Privileged": True}) - self.assertEqual(args[1]['headers'], - {'Content-Type': 'application/json'}) - self.assertEqual( - args[1]['timeout'], - DEFAULT_TIMEOUT_SECONDS - ) + if six.PY2: + try: + self.client.start(fake_api.FAKE_CONTAINER_ID, privileged=True) + except DeprecationWarning as e: + return + except Exception as e: + self.fail('Command should not raise exception: {0}'.format(e)) + else: + self.fail('Expected a DeprecationWarning') + else: + with self.assertWarns(DeprecationWarning): + self.client.start(fake_api.FAKE_CONTAINER_ID, privileged=True) def test_start_container_with_dict_instead_of_id(self): try: |