{"action":"created","issue":{"url":"https://api.github.com/repos/ansible/ansible/issues/9544","repository_url":"https://api.github.com/repos/ansible/ansible","labels_url":"https://api.github.com/repos/ansible/ansible/issues/9544/labels{/name}","comments_url":"https://api.github.com/repos/ansible/ansible/issues/9544/comments","events_url":"https://api.github.com/repos/ansible/ansible/issues/9544/events","html_url":"https://github.com/ansible/ansible/issues/9544","id":48521051,"number":9544,"title":"ssh + sudo password can hang indefinitely","user":{"login":"stanhu","id":963826,"avatar_url":"https://avatars.githubusercontent.com/u/963826?v=3","gravatar_id":"","url":"https://api.github.com/users/stanhu","html_url":"https://github.com/stanhu","followers_url":"https://api.github.com/users/stanhu/followers","following_url":"https://api.github.com/users/stanhu/following{/other_user}","gists_url":"https://api.github.com/users/stanhu/gists{/gist_id}","starred_url":"https://api.github.com/users/stanhu/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stanhu/subscriptions","organizations_url":"https://api.github.com/users/stanhu/orgs","repos_url":"https://api.github.com/users/stanhu/repos","events_url":"https://api.github.com/users/stanhu/events{/privacy}","received_events_url":"https://api.github.com/users/stanhu/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/ansible/ansible/labels/bug_report","name":"bug_report","color":"fbca04"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2014-11-12T15:15:49Z","updated_at":"2016-04-19T17:49:59Z","closed_at":null,"body":"##### Issue Type:\r\n\r\nBug Report\r\n\r\n##### Ansible Version:\r\n\r\n$ ansible --version\r\nansible 1.7.2\r\n\r\n##### Environment:\r\n\r\nMacOS (also occurs on Ubuntu 14.04)\r\n\r\n##### Summary:\r\n\r\nssh logins that require sudo passwords can hang indefinitely.\r\n\r\n##### Steps To Reproduce:\r\n\r\nI think the bug could be be reproduced if you enable sudo passwords and change sudo to a program that runs 'sleep 10' before it executes. Then run a playbook with the \"--ask-sudo\" parameter with that machine in the inventory.\r\n\r\nHere is what I think is happening:\r\n\r\n1. Ansible attempts to ssh into a machine.\r\n2. Ansible successfully logs in and attempts to run 'sudo'.\r\n3. sudo takes a while and requires a password to be entered.\r\n4. Ansible does a select() on the read socket.\r\n5. The select() times out after 10 seconds. Ansible waits for the SSH process to terminate (from ansible/runner/connection_plugins/ssh.py):\r\n\r\n```\r\n         if not rfd:\r\n                    # timeout. wrap up process communication                                                                                                                                 \r\n                    stdout = p.communicate()\r\n                    raise errors.AnsibleError('ssh connection error waiting for sudo or su password prompt')\r\n```\r\nHowever, since Ansible is logged in and sudo is running, the process never terminates. communicate() gets stuck.\r\n\r\nEssentially, I think this is a corner case where the ssh login succeeds, but the time it takes for sudo to execute and ask for a password exceeds the timeout. Since the ssh session was successful, the ssh process will never return, causing Ansible to hang indefinitely.\r\n\r\nI verified this was happening by adding a 'continue', here:\r\n\r\n```\r\n   if not rfd:\r\n                    continue\r\n                    # timeout. wrap up process communication                                                                                                                                 \r\n                    stdout = p.communicate()\r\n```\r\n\r\nThis worked--essentially a short time later, the select() returned successfully, and Ansible functioned well. To confirm this, I added some debug statements using time.time(). Here is what I saw:\r\n\r\n1. t = 0: start of first select()\r\n2. t = 10.000742: timeout occurs\r\n3. t = 10.000874: second select() returns successfully\r\n\r\nHow to fix this? Ideally, we would have some way of knowing that the ssh session successfully logged in but was waiting for sudo. I don't think there is a foolproof way of knowing this. \r\n\r\nIn any case, communicate() should have a timeout, so that if ssh fails to terminate, we either terminate the ssh process or run select() again just to be sure. There are some ideas here for how to implement a timeout:\r\n\r\nhttp://stackoverflow.com/questions/1191374/subprocess-with-timeout \r\n\r\nFor now, I've worked around the problem by changing timeout = 20, but I think the code still needs to prevent communicate() from getting stuck.\r\n \r\n##### Expected Results:\r\n\r\nssh logins and sudo executes fine\r\n\r\n##### Actual Results:\r\n\r\nssh process never returns and causes Ansible to get stuck\r\n\r\nI think a similar issue was reported in issue #8058.\r\n"},"comment":{"url":"https://api.github.com/repos/ansible/ansible/issues/comments/212039108","html_url":"https://github.com/ansible/ansible/issues/9544#issuecomment-212039108","issue_url":"https://api.github.com/repos/ansible/ansible/issues/9544","id":212039108,"user":{"login":"d3matt","id":1126638,"avatar_url":"https://avatars.githubusercontent.com/u/1126638?v=3","gravatar_id":"","url":"https://api.github.com/users/d3matt","html_url":"https://github.com/d3matt","followers_url":"https://api.github.com/users/d3matt/followers","following_url":"https://api.github.com/users/d3matt/following{/other_user}","gists_url":"https://api.github.com/users/d3matt/gists{/gist_id}","starred_url":"https://api.github.com/users/d3matt/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/d3matt/subscriptions","organizations_url":"https://api.github.com/users/d3matt/orgs","repos_url":"https://api.github.com/users/d3matt/repos","events_url":"https://api.github.com/users/d3matt/events{/privacy}","received_events_url":"https://api.github.com/users/d3matt/received_events","type":"User","site_admin":false},"created_at":"2016-04-19T17:49:59Z","updated_at":"2016-04-19T17:49:59Z","body":"should be able to close this now that #14400 is merged... I should've gone looking for tickets when I fixed that"}}