From ce60327b609f9967d6dab28de1bf17afc01bb0bc Mon Sep 17 00:00:00 2001 From: Mark Goddard Date: Thu, 12 Oct 2017 11:19:23 +0100 Subject: [PATCH] Fix SSH reconnection for docker role in Ansible 2.3 In ansible 2.3, the path to SSH persistent connection sockets was changed to use a SHA1 hash of the connection parameters, so the workaround to force a reconnection was broken. This change removes all ControlPath sockets from the ansible control host. --- ansible/roles/docker/tasks/main.yml | 33 ++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/ansible/roles/docker/tasks/main.yml b/ansible/roles/docker/tasks/main.yml index ce611fde9..9b5f3244f 100644 --- a/ansible/roles/docker/tasks/main.yml +++ b/ansible/roles/docker/tasks/main.yml @@ -17,6 +17,9 @@ # After adding the user to the docker group, we need to log out and in again to # pick up the group membership. We do this by removing the SSH ControlPersist # connection. + +# NOTE: This method does not work in Ansible 2.3, which uses a SHA1 hash of the +# connection parameters to determine the control persist socket path. - name: Drop the persistent SSH connection to activate the new group membership local_action: module: shell ssh -O stop {{ cp_hostname }} -o ControlPath={{ cp_path }} @@ -26,13 +29,41 @@ - "'No such file or directory' not in socket_removal.stderr" with_items: "{{ play_hosts }}" run_once: True - when: group_result|changed + when: + - group_result|changed + - ansible_version | version_compare('2.3', 'lt') vars: cp_hostname: "{{ hostvars[item].ansible_host|default(inventory_hostname) }}" cp_username: "{{ hostvars[item].ansible_user }}" cp_port: "{{ hostvars[item].ansible_ssh_port|default('22') }}" cp_path: "~/.ansible/cp/ansible-ssh-{{ cp_hostname }}-{{ cp_port }}-{{ cp_username }}" +# NOTE: For Ansible 2.3+, ideally we'd use a meta task with the +# reset_connection option but due to +# https://github.com/ansible/ansible/issues/27520 this does not work (checked +# in Ansible 2.3.2.0). Instead, we use the heavy handed method of removing all +# ansible control sockets. Limitation: if this user is running another ansible +# process, we will kill its connections. +- name: Find persistent SSH connection control sockets + local_action: + module: find + file_type: any + path: "~/.ansible/cp/" + patterns: '[a-f0-9]{10}' + use_regex: True + register: cp_sockets + run_once: True + when: + - group_result|changed + - ansible_version | version_compare('2.3', 'ge') + +- name: Drop all persistent SSH connections to activate the new group membership + local_action: + module: shell ssh -O stop None -o ControlPath={{ item.path }} + with_items: "{{ cp_sockets.files }}" + run_once: True + when: not cp_sockets|skipped + - name: Ensure Docker daemon is started service: name: docker