From 59ccd8a782b64d91e3b4609b750c963b253fbb81 Mon Sep 17 00:00:00 2001 From: Dmitri Date: Wed, 28 Dec 2016 23:23:08 -0800 Subject: Fix readonly in mounts. Signed-off-by: Dmitri Zimine dz@stackstorm.com --- docker/types/services.py | 3 ++- tests/unit/types.py | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 tests/unit/types.py diff --git a/docker/types/services.py b/docker/types/services.py index 5041f89..d76561e 100644 --- a/docker/types/services.py +++ b/docker/types/services.py @@ -135,6 +135,7 @@ class Mount(dict): 'Only acceptable mount types are `bind` and `volume`.' ) self['Type'] = type + self['ReadOnly'] = read_only if type == 'bind': if propagation is not None: @@ -174,7 +175,7 @@ class Mount(dict): else: target = parts[1] source = parts[0] - read_only = not (len(parts) == 3 or parts[2] == 'ro') + read_only = not (len(parts) == 2 or parts[2] == 'rw') return cls(target, source, read_only=read_only) diff --git a/tests/unit/types.py b/tests/unit/types.py new file mode 100644 index 0000000..5a73837 --- /dev/null +++ b/tests/unit/types.py @@ -0,0 +1,16 @@ +import unittest +from docker.types.services import Mount + + +class TestMounts(unittest.TestCase): + def test_parse_mount_string_docker(self): + mount = Mount.parse_mount_string("foo/bar:/buz:ro") + self.assertEqual(mount['Source'], "foo/bar") + self.assertEqual(mount['Target'], "/buz") + self.assertEqual(mount['ReadOnly'], True) + + mount = Mount.parse_mount_string("foo/bar:/buz:rw") + self.assertEqual(mount['ReadOnly'], False) + + mount = Mount.parse_mount_string("foo/bar:/buz") + self.assertEqual(mount['ReadOnly'], False) -- cgit v1.2.1 From a96073199939c6f01894414a8a9eb78409ac4bb5 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 9 Jan 2017 14:33:58 -0800 Subject: Additional parse_mount_string tests Signed-off-by: Joffrey F --- tests/unit/dockertypes_test.py | 34 ++++++++++++++++++++++++++++++++-- tests/unit/types.py | 16 ---------------- 2 files changed, 32 insertions(+), 18 deletions(-) delete mode 100644 tests/unit/types.py diff --git a/tests/unit/dockertypes_test.py b/tests/unit/dockertypes_test.py index 2480b9e..5cf5f4e 100644 --- a/tests/unit/dockertypes_test.py +++ b/tests/unit/dockertypes_test.py @@ -5,9 +5,9 @@ import unittest import pytest from docker.constants import DEFAULT_DOCKER_API_VERSION -from docker.errors import InvalidVersion +from docker.errors import InvalidArgument, InvalidVersion from docker.types import ( - EndpointConfig, HostConfig, IPAMConfig, IPAMPool, LogConfig, Ulimit, + EndpointConfig, HostConfig, IPAMConfig, IPAMPool, LogConfig, Mount, Ulimit, ) @@ -253,3 +253,33 @@ class IPAMConfigTest(unittest.TestCase): 'IPRange': None, }] }) + + +class TestMounts(unittest.TestCase): + def test_parse_mount_string_ro(self): + mount = Mount.parse_mount_string("/foo/bar:/baz:ro") + self.assertEqual(mount['Source'], "/foo/bar") + self.assertEqual(mount['Target'], "/baz") + self.assertEqual(mount['ReadOnly'], True) + + def test_parse_mount_string_rw(self): + mount = Mount.parse_mount_string("/foo/bar:/baz:rw") + self.assertEqual(mount['Source'], "/foo/bar") + self.assertEqual(mount['Target'], "/baz") + self.assertEqual(mount['ReadOnly'], False) + + def test_parse_mount_string_short_form(self): + mount = Mount.parse_mount_string("/foo/bar:/baz") + self.assertEqual(mount['Source'], "/foo/bar") + self.assertEqual(mount['Target'], "/baz") + self.assertEqual(mount['ReadOnly'], False) + + def test_parse_mount_string_no_source(self): + mount = Mount.parse_mount_string("foo/bar") + self.assertEqual(mount['Source'], None) + self.assertEqual(mount['Target'], "foo/bar") + self.assertEqual(mount['ReadOnly'], False) + + def test_parse_mount_string_invalid(self): + with pytest.raises(InvalidArgument): + Mount.parse_mount_string("foo:bar:baz:rw") diff --git a/tests/unit/types.py b/tests/unit/types.py deleted file mode 100644 index 5a73837..0000000 --- a/tests/unit/types.py +++ /dev/null @@ -1,16 +0,0 @@ -import unittest -from docker.types.services import Mount - - -class TestMounts(unittest.TestCase): - def test_parse_mount_string_docker(self): - mount = Mount.parse_mount_string("foo/bar:/buz:ro") - self.assertEqual(mount['Source'], "foo/bar") - self.assertEqual(mount['Target'], "/buz") - self.assertEqual(mount['ReadOnly'], True) - - mount = Mount.parse_mount_string("foo/bar:/buz:rw") - self.assertEqual(mount['ReadOnly'], False) - - mount = Mount.parse_mount_string("foo/bar:/buz") - self.assertEqual(mount['ReadOnly'], False) -- cgit v1.2.1 From 180dd6997489c7c5ccdd4c9bfbd213f0298143c4 Mon Sep 17 00:00:00 2001 From: Joffrey F Date: Mon, 9 Jan 2017 14:34:25 -0800 Subject: Raise InvalidArgument exception when invalid arguments are provided Signed-off-by: Joffrey F --- docker/errors.py | 4 ++++ docker/types/services.py | 12 ++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/docker/errors.py b/docker/errors.py index 05f4cae..95c462b 100644 --- a/docker/errors.py +++ b/docker/errors.py @@ -93,6 +93,10 @@ class InvalidConfigFile(DockerException): pass +class InvalidArgument(DockerException): + pass + + class DeprecatedMethod(DockerException): pass diff --git a/docker/types/services.py b/docker/types/services.py index d76561e..b52afd2 100644 --- a/docker/types/services.py +++ b/docker/types/services.py @@ -131,7 +131,7 @@ class Mount(dict): self['Target'] = target self['Source'] = source if type not in ('bind', 'volume'): - raise errors.DockerError( + raise errors.InvalidArgument( 'Only acceptable mount types are `bind` and `volume`.' ) self['Type'] = type @@ -143,7 +143,7 @@ class Mount(dict): 'Propagation': propagation } if any([labels, driver_config, no_copy]): - raise errors.DockerError( + raise errors.InvalidArgument( 'Mount type is binding but volume options have been ' 'provided.' ) @@ -158,7 +158,7 @@ class Mount(dict): if volume_opts: self['VolumeOptions'] = volume_opts if propagation: - raise errors.DockerError( + raise errors.InvalidArgument( 'Mount type is volume but `propagation` argument has been ' 'provided.' ) @@ -167,11 +167,11 @@ class Mount(dict): def parse_mount_string(cls, string): parts = string.split(':') if len(parts) > 3: - raise errors.DockerError( + raise errors.InvalidArgument( 'Invalid mount format "{0}"'.format(string) ) if len(parts) == 1: - return cls(target=parts[0]) + return cls(target=parts[0], source=None) else: target = parts[1] source = parts[0] @@ -229,7 +229,7 @@ class UpdateConfig(dict): if delay is not None: self['Delay'] = delay if failure_action not in ('pause', 'continue'): - raise errors.DockerError( + raise errors.InvalidArgument( 'failure_action must be either `pause` or `continue`.' ) self['FailureAction'] = failure_action -- cgit v1.2.1