Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ssh connection reset and ssh tokens in controlpath #68341

Closed
apatard opened this issue Mar 19, 2020 · 4 comments · Fixed by #73708
Closed

ssh connection reset and ssh tokens in controlpath #68341

apatard opened this issue Mar 19, 2020 · 4 comments · Fixed by #73708
Labels
affects_2.9 This issue/PR affects Ansible v2.9 bug This issue/PR relates to a bug. has_pr This issue has an associated PR. P3 Priority 3 - Approved, No Time Limitation python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team.

Comments

@apatard
Copy link

apatard commented Mar 19, 2020

SUMMARY

When investigating ansible-community/molecule-vagrant#1, I found out that meta: reset_connection is not working due to the reset() function of the ssh.py connection plugin not being able to find the connection socket. It turns out that molecule is using control_path = %(directory)s/%%h-%%p-%%r. For instance, it's translated into ControlPath=/home/vagrant/.ansible/cp/%h-%p-%r on the ssh command line.

The reset code does :

        run_reset = False
        if controlpersist and len(cp_arg) > 0:
            cp_path = cp_arg[0].split(b"=", 1)[-1]
            if os.path.exists(cp_path):
                run_reset = True
        elif controlpersist:
            run_reset = True

Due to the content of the ControlPath argument, it will set cp_path to /home/vagrant/.ansible/cp/%h-%p-%r and of course, the os.path.exists(cp_path) will fail, making "meta: reset_connection" useless.
fwiw, looks like this bug as been introduced by the fix for #42991

A crude workaround would be changing the test to if b'%' in cp_path or os.path.exists(cp_path). It may be better to interpolate the ssh tokens but I've no idea if it's really possible and how to do that.

ISSUE TYPE
  • Bug Report
COMPONENT NAME

ssh connection plugin

ANSIBLE VERSION
ansible --version
ansible 2.9.6
  config file = /home/rtp/devel/hupstream/ansible/molecule-vagrant-zuul/t/ansible.cfg
  configured module search path = ['/home/rtp/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/rtp/.local/lib/python3.7/site-packages/ansible
  executable location = /home/rtp/.local/bin/ansible
  python version = 3.7.3 (default, Dec 20 2019, 18:57:59) [GCC 8.3.0]
CONFIGURATION
[defaults]
ansible_managed = Ansible managed: Do NOT edit this file manually!
display_failed_stderr = True
forks = 50
retry_files_enabled = False
host_key_checking = False
nocows = 1
interpreter_python = auto
[ssh_connection]
scp_if_ssh = True
control_path = %(directory)s/%%h-%%p-%%r
pipelining = True

OS / ENVIRONMENT

Debian stable

STEPS TO REPRODUCE

Since I was testing that for molecule-vagrant, I've a Vagrantfile and a converge.yml file:

Vagrantfile:

Vagrant.configure("2") do |c|
  c.vm.define 'test2' do |v|
    v.vm.hostname = 'test2'
    v.vm.box = 'debian/buster64'
  end
  c.vm.provision :ansible do |ansible|
    ansible.playbook = "converge.yml"
  end
end

converge.yml

---
- name: Converge
  hosts: all
  gather_facts: false
  tasks:
    - name: Create test group
      group:
        name: testgroup
      become: true
    - name: Add vagrant user to test group
      user:
        name: vagrant
        groups: testgroup
        append: yes
      become: true
    - name: reset connection
      meta: reset_connection
    - name: Get vagrant user info
      command: id -nG
      register: user_grps
    - name: Print user_grps
      debug:
        var: user_grps
    - name: Check user in vagrant group
      assert:
        that:
          - "'testgroup' in user_grps.stdout.split(' ')"

ansible.cfg

[ssh_connection]
control_path = %(directory)s/%%h-%%p-%%r
EXPECTED RESULTS

The run of the converge.yml should work

ACTUAL RESULTS
TASK [Check user in vagrant group] *********************************************
fatal: [test2]: FAILED! => {
    "assertion": "'testgroup' in user_grps.stdout.split(' ')",
    "changed": false,
    "evaluated_to": false,
    "msg": "Assertion failed"
}
@ansibot
Copy link
Contributor

ansibot commented Mar 19, 2020

Files identified in the description:

If these files are inaccurate, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibot ansibot added affects_2.9 This issue/PR affects Ansible v2.9 bug This issue/PR relates to a bug. needs_triage Needs a first human triage before being processed. python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team. labels Mar 19, 2020
@bcoca bcoca added P3 Priority 3 - Approved, No Time Limitation and removed needs_triage Needs a first human triage before being processed. labels Apr 14, 2020
@apatard
Copy link
Author

apatard commented Sep 23, 2020

Any idea on how to fix this ?

@sivel
Copy link
Member

sivel commented Sep 23, 2020

I think the code based fix will be something roughly like this:

diff --git a/lib/ansible/plugins/connection/ssh.py b/lib/ansible/plugins/connection/ssh.py
index ed44a035fe..fa5ad29cf2 100644
--- a/lib/ansible/plugins/connection/ssh.py
+++ b/lib/ansible/plugins/connection/ssh.py
@@ -1266,7 +1266,7 @@ class Connection(ConnectionBase):
         run_reset = False
         if controlpersist and len(cp_arg) > 0:
             cp_path = cp_arg[0].split(b"=", 1)[-1]
-            if os.path.exists(cp_path):
+            if os.path.exists(cp_path) or re.search(r'%[hprC]', cp_path):
                 run_reset = True
         elif controlpersist:
             run_reset = True

I haven't tested this, and am not actively pursuing this fix any further. If you want to test this, and get together a pull request, please feel free to do so.

@apatard
Copy link
Author

apatard commented Sep 23, 2020

thanks. I'll test that. I guess this would work but I'm still worried about re-introducing bug #42991.

@ansibot ansibot added the has_pr This issue has an associated PR. label Jan 23, 2021
LaurentMarchelli added a commit to LaurentMarchelli/ansible that referenced this issue Feb 23, 2021
reset now expands ssh tokens before checking path existence.
Successfully tested with molecule and meta: reset_connection.

Fix : ansible#68341
May Fix : ansible#66414
LaurentMarchelli added a commit to LaurentMarchelli/ansible that referenced this issue Feb 23, 2021
reset now expands ssh tokens before checking path existence.
Successfully tested with molecule and meta: reset_connection.

Fixes: ansible#68341
LaurentMarchelli added a commit to LaurentMarchelli/ansible that referenced this issue Feb 23, 2021
reset now expands ssh tokens before checking path existence.
Successfully tested with molecule and meta: reset_connection.

Fixes: ansible#68341
@ansible ansible locked and limited conversation to collaborators Mar 31, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
affects_2.9 This issue/PR affects Ansible v2.9 bug This issue/PR relates to a bug. has_pr This issue has an associated PR. P3 Priority 3 - Approved, No Time Limitation python3 support:core This issue/PR relates to code supported by the Ansible Engineering Team.
Projects
None yet
4 participants