From 83423974277a0c0cbc3d123a5a3e402408b01783 Mon Sep 17 00:00:00 2001 From: Andrew Pashkin Date: Fri, 2 Oct 2015 00:44:52 +0300 Subject: [PATCH] Harden matching running containers by "command" in the Docker module Before this patch: - Command was matched if 'Command' field of docker-py representation of Docker container ends with 'command' passed to Ansible docker module by user. - That can give false positives and false negatives. - For example: a) If 'command' was set up with more than one spaces, like 'command=sleep 123', it would be never matched again with a container(s) launched by this task. Because after launching, command would be normalized and appear, in docker-py API call, just as 'sleep 123' - with one space. This is false negative case. b) If 'entrypoint + command = command', for example 'sleep + 123 = sleep 123', module would give false positive match. This patch fixes it, by making matching more explicit - against 'Config'->Cmd' field of 'docker inspect' output, provided by docker-py API and with proper normalization of user input by splitting it to tokens with 'shlex.split()'. --- lib/ansible/modules/cloud/docker/docker.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/ansible/modules/cloud/docker/docker.py b/lib/ansible/modules/cloud/docker/docker.py index a6eb65e3d9a..8882c8d7b04 100644 --- a/lib/ansible/modules/cloud/docker/docker.py +++ b/lib/ansible/modules/cloud/docker/docker.py @@ -1389,8 +1389,8 @@ class DockerManager(object): """ command = self.module.params.get('command') - if command: - command = command.strip() + if command is not None: + command = shlex.split(command) name = self.module.params.get('name') if name and not name.startswith('/'): name = '/' + name @@ -1417,13 +1417,10 @@ class DockerManager(object): details = _docker_id_quirk(details) running_image = normalize_image(details['Config']['Image']) - running_command = container['Command'].strip() image_matches = running_image in repo_tags - # if a container has an entrypoint, `command` will actually equal - # '{} {}'.format(entrypoint, command) - command_matches = (not command or running_command.endswith(command)) + command_matches = command == details['Config']['Cmd'] matches = image_matches and command_matches