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

[WIP] [2.8] connection/docker: add support for privilege escalation #56277

merged 2 commits into from May 21, 2019
Changes from 1 commit
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.


Just for now

@@ -0,0 +1,4 @@
- Fix privilege escalation support for the docker connection plugin when
credentials needs to be supplied (e.g. sudo with password).
@@ -39,6 +39,7 @@

import distutils.spawn
import fcntl
import os
import os.path
import subprocess
@@ -47,6 +48,7 @@
from distutils.version import LooseVersion

import ansible.constants as C
from ansible.compat import selectors
from ansible.errors import AnsibleError, AnsibleFileNotFound
from ansible.module_utils.six.moves import shlex_quote
from ansible.module_utils._text import to_bytes, to_native, to_text
@@ -205,10 +207,55 @@ def exec_command(self, cmd, in_data=None, sudoable=False):

display.vvv("EXEC %s" % (local_cmd,), host=self._play_context.remote_addr)
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
p = subprocess.Popen(local_cmd, shell=False, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)

p = subprocess.Popen(

if self.become and self.become.expect_prompt() and sudoable:
display.debug("handling privilege escalation")
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) | os.O_NONBLOCK)
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) | os.O_NONBLOCK)

selector = selectors.DefaultSelector()
selector.register(p.stdout, selectors.EVENT_READ)
selector.register(p.stderr, selectors.EVENT_READ)

become_output = b''
while not self.become.check_success(become_output) and not self.become.check_password_prompt(become_output):
events =
if not events:
stdout, stderr = p.communicate()
raise AnsibleError('timeout waiting for privilege escalation password prompt:\n' + to_native(become_output))

for key, event in events:
if key.fileobj == p.stdout:
chunk =

This comment has been minimized.

Copy link

felixfontein May 9, 2019

Author Contributor

I don't think this break should be there (and I guess I missed it in the original PR). It's not in, either. @larsks where does it come from?

This comment has been minimized.

Copy link

larsks May 9, 2019


Huh, I haven't the foggiest idea. I didn't do any editing of that content that I recall. Funny that it works. I guess we submit a patch and fix it in the backports? Funny that everything still works. I wish this was all handled in one place...

This comment has been minimized.

Copy link

felixfontein May 10, 2019

Author Contributor

I've created #56288 and will include it in this backport once it is merged.

Your stable-2.7 does not have this code included though...

elif key.fileobj == p.stderr:
chunk =

if not chunk:
stdout, stderr = p.communicate()
raise AnsibleError('privilege output closed while waiting for password prompt:\n' + to_native(become_output))
become_output += chunk

if not self.become.check_success(become_output):
p.stdin.write(to_bytes(self._play_context.become_pass, errors='surrogate_or_strict') + b'\n')
fcntl.fcntl(p.stdout, fcntl.F_SETFL, fcntl.fcntl(p.stdout, fcntl.F_GETFL) & ~os.O_NONBLOCK)
fcntl.fcntl(p.stderr, fcntl.F_SETFL, fcntl.fcntl(p.stderr, fcntl.F_GETFL) & ~os.O_NONBLOCK)

display.debug("getting output with communicate()")
stdout, stderr = p.communicate(in_data)
display.debug("done communicating")

display.debug("done with docker.exec_command()")
return (p.returncode, stdout, stderr)

def _prefix_login_path(self, remote_path):
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.