From 48541910bffb8e178000b1f3dd32171792f0922f Mon Sep 17 00:00:00 2001 From: Felix Fontein Date: Fri, 16 Aug 2019 15:23:03 +0200 Subject: [PATCH] docker_container: add mount endpoint collision detection (#60384) * Add mount endpoint collision detection. * Add changelog. * Fix error. --- ...ker_container-mount-endpoint-collision.yml | 2 ++ .../modules/cloud/docker/docker_container.py | 21 +++++++++++ .../tasks/tests/mounts-volumes.yml | 36 +++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 changelogs/fragments/60384-docker_container-mount-endpoint-collision.yml diff --git a/changelogs/fragments/60384-docker_container-mount-endpoint-collision.yml b/changelogs/fragments/60384-docker_container-mount-endpoint-collision.yml new file mode 100644 index 00000000000..6865e1a6e7e --- /dev/null +++ b/changelogs/fragments/60384-docker_container-mount-endpoint-collision.yml @@ -0,0 +1,2 @@ +minor_changes: +- "docker_container - now tests for mount endpoint collisions (for both ``mounts`` and ``volumes``) to abort early when collisions are found" diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index 3991c410f82..a6743a84235 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -1290,6 +1290,8 @@ class TaskParameters(DockerBaseClass): self.mounts_opt, self.expected_mounts = self._process_mounts() + self._check_mount_target_collisions() + for param_name in ["device_read_bps", "device_write_bps"]: if client.module.params.get(param_name): self._process_rate_bps(option=param_name) @@ -1842,6 +1844,25 @@ class TaskParameters(DockerBaseClass): return mode return 'container:{0}'.format(container['Id']) + def _check_mount_target_collisions(self): + last = dict() + + def f(t, name): + if t in last: + if name == last[t]: + self.client.fail('The mount point "{0}" appears twice in the {1} option'.format(t, name)) + else: + self.client.fail('The mount point "{0}" appears both in the {1} and {2} option'.format(t, name, last[t])) + last[t] = name + + if self.expected_mounts: + for t in [m['target'] for m in self.expected_mounts]: + f(t, 'mounts') + if self.volumes: + for v in self.volumes: + vs = v.split(':') + f(vs[0 if len(vs) == 1 else 1], 'volumes') + class Container(DockerBaseClass): diff --git a/test/integration/targets/docker_container/tasks/tests/mounts-volumes.yml b/test/integration/targets/docker_container/tasks/tests/mounts-volumes.yml index 218caad65f8..0f7e252e431 100644 --- a/test/integration/targets/docker_container/tasks/tests/mounts-volumes.yml +++ b/test/integration/targets/docker_container/tasks/tests/mounts-volumes.yml @@ -101,6 +101,24 @@ register: mounts_5 ignore_errors: yes +- name: mounts (endpoint collision) + docker_container: + image: alpine:3.8 + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + state: started + mounts: + - source: /home + target: /x + type: bind + - source: /etc + target: /x + type: bind + read_only: no + force_kill: yes + register: mounts_6 + ignore_errors: yes + - name: cleanup docker_container: name: "{{ cname }}" @@ -115,6 +133,8 @@ - mounts_3 is not changed - mounts_4 is changed - mounts_5 is changed + - mounts_6 is failed + - "'The mount point \"/x\" appears twice in the mounts option' == mounts_6.msg" when: docker_py_version is version('2.6.0', '>=') - assert: that: @@ -206,6 +226,7 @@ - mounts_volumes_2 is not changed - mounts_volumes_3 is changed - mounts_volumes_4 is failed + - "'The mount point \"/tmp\" appears both in the volumes and mounts option' in mounts_volumes_4.msg" when: docker_py_version is version('2.6.0', '>=') - assert: that: @@ -319,6 +340,19 @@ force_kill: yes register: volumes_5 +- name: volumes (collision) + docker_container: + image: alpine:3.8 + command: '/bin/sh -c "sleep 10m"' + name: "{{ cname }}" + state: started + volumes: + - "/etc:/tmp" + - "/home:/tmp:ro" + force_kill: yes + register: volumes_6 + ignore_errors: yes + - name: cleanup docker_container: name: "{{ cname }}" @@ -333,6 +367,8 @@ - volumes_3 is not changed - volumes_4 is changed - volumes_5 is changed + - volumes_6 is failed + - "'The mount point \"/tmp\" appears twice in the volumes option' in volumes_6.msg" #################################################################### ## volumes_from ####################################################