<p dir="auto">Hello. For some particularly purposes I'm using restricted user for getting access to the servers by ssh. This user has «no-pty» option in ssh authorized key and when I run task through ansible without «sudo: yes» option it runs great. But sudoable commands is crashed with this traceback:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="GATHERING FACTS ***************************************************************
fatal: [alma.relax.ru] =&gt; Traceback (most recent call last):
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/__init__.py&quot;, line 364, in _executor
    exec_rc = self._executor_internal(host, new_stdin)
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/__init__.py&quot;, line 443, in _executor_internal
    return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port, complex_args=complex_args)
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/__init__.py&quot;, line 597, in _executor_internal_inner
    result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/action_plugins/normal.py&quot;, line 54, in run
    return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject, complex_args=complex_args)
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/__init__.py&quot;, line 333, in _execute_module
    res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/__init__.py&quot;, line 637, in _low_level_exec_command
    rc, stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable, executable=executable)
  File &quot;/usr/lib/python2.6/site-packages/ansible/runner/connection_plugins/paramiko_ssh.py&quot;, line 203, in exec_command
    height=int(os.getenv('LINES', 0)))
  File &quot;/usr/lib/python2.6/site-packages/paramiko/channel.py&quot;, line 158, in get_pty
    self._wait_for_event()
  File &quot;/usr/lib/python2.6/site-packages/paramiko/channel.py&quot;, line 1084, in _wait_for_event
    raise e
SSHException: Channel closed."><pre class="notranslate"><code class="notranslate">GATHERING FACTS ***************************************************************
fatal: [alma.relax.ru] =&gt; Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 364, in _executor
    exec_rc = self._executor_internal(host, new_stdin)
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 443, in _executor_internal
    return self._executor_internal_inner(host, self.module_name, self.module_args, inject, port, complex_args=complex_args)
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 597, in _executor_internal_inner
    result = handler.run(conn, tmp, module_name, module_args, inject, complex_args)
  File "/usr/lib/python2.6/site-packages/ansible/runner/action_plugins/normal.py", line 54, in run
    return self.runner._execute_module(conn, tmp, module_name, module_args, inject=inject, complex_args=complex_args)
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 333, in _execute_module
    res = self._low_level_exec_command(conn, cmd, tmp, sudoable=True)
  File "/usr/lib/python2.6/site-packages/ansible/runner/__init__.py", line 637, in _low_level_exec_command
    rc, stdin, stdout, stderr = conn.exec_command(cmd, tmp, sudo_user, sudoable=sudoable, executable=executable)
  File "/usr/lib/python2.6/site-packages/ansible/runner/connection_plugins/paramiko_ssh.py", line 203, in exec_command
    height=int(os.getenv('LINES', 0)))
  File "/usr/lib/python2.6/site-packages/paramiko/channel.py", line 158, in get_pty
    self._wait_for_event()
  File "/usr/lib/python2.6/site-packages/paramiko/channel.py", line 1084, in _wait_for_event
    raise e
SSHException: Channel closed.
</code></pre></div>
<p dir="auto">I've scoured ansible source code and found paramiko function get_pty() call in the paramiko_ssh.py file with shady comment «sudo <em>usually</em> requires a PTY» and without any checks if that is really necessary. I have disabled following option in my sudoers: <code class="notranslate">#Defaults    requiretty</code> and I really don't need that.</p>
<p dir="auto">I've just comment out this function call and, in the first glance, all starts work seamless. After that, I read discussion in <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="9495056" data-permission-text="Title is private" data-url="https://github.com/ansible/ansible/issues/1801" data-hovercard-type="pull_request" data-hovercard-url="/ansible/ansible/pull/1801/hovercard" href="https://github.com/ansible/ansible/pull/1801">#1801</a> and it shed some light about problem. I've been using fabric with option <code class="notranslate">sudo.pty = False</code> in my configuration on CentOS and FreeBSD for two years without any problems. I think some additional option <code class="notranslate">pty: no</code> following with <code class="notranslate">sudo: yes</code> would be great.</p>
<p dir="auto">I don't familiar with ansible internal architecture so I haven't written a patch by myself yet.</p>
<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">files/replace module</p>
<h5 dir="auto">ANSIBLE VERSION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="2.4.0.0"><pre class="notranslate"><code class="notranslate">2.4.0.0
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<p dir="auto">N/A</p>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">N/A</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">when using before/after to select text to apply the replace to, replace still acts on whole file</p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<p dir="auto">Look at the code, eg try before/after patterns that exist in file which regexp that appears outside the intended text selection area  :-)</p>
<p dir="auto">ansible/modules/files/replace.py:</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="if result[1] &gt; 0 and section != result[0]: 
     if pattern: 
         result = (contents.replace(section, result[0]), result[1])"><pre class="notranslate"><code class="notranslate">if result[1] &gt; 0 and section != result[0]: 
     if pattern: 
         result = (contents.replace(section, result[0]), result[1])
</code></pre></div>
<p dir="auto">Should  be "section.replace" rather than "contents.replace"</p>