mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Lock around SSH connectivity to new hosts in host checking mode such that prompts for host approval
messages do not get interlaced.
This commit is contained in:
parent
cb26945d54
commit
1683d44d2e
1 changed files with 32 additions and 0 deletions
|
@ -93,6 +93,22 @@ class Connection(object):
|
||||||
os.write(self.wfd, "%s\n" % self.password)
|
os.write(self.wfd, "%s\n" % self.password)
|
||||||
os.close(self.wfd)
|
os.close(self.wfd)
|
||||||
|
|
||||||
|
def not_in_host_file(self, host):
|
||||||
|
host_file = os.path.expanduser("~/.ssh/known_hosts")
|
||||||
|
if not os.path.exists(host_file):
|
||||||
|
print "previous known host file not found"
|
||||||
|
return True
|
||||||
|
host_fh = open(host_file)
|
||||||
|
data = host_fh.read()
|
||||||
|
host_fh.close()
|
||||||
|
for line in data.split("\n"):
|
||||||
|
if line is None or line.find(" ") == -1:
|
||||||
|
continue
|
||||||
|
tokens = line.split()
|
||||||
|
if host in tokens[0]:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def exec_command(self, cmd, tmp_path, sudo_user,sudoable=False, executable='/bin/sh'):
|
def exec_command(self, cmd, tmp_path, sudo_user,sudoable=False, executable='/bin/sh'):
|
||||||
''' run a command on the remote host '''
|
''' run a command on the remote host '''
|
||||||
|
|
||||||
|
@ -109,6 +125,16 @@ class Connection(object):
|
||||||
ssh_cmd.append(sudocmd)
|
ssh_cmd.append(sudocmd)
|
||||||
|
|
||||||
vvv("EXEC %s" % ssh_cmd, host=self.host)
|
vvv("EXEC %s" % ssh_cmd, host=self.host)
|
||||||
|
|
||||||
|
not_in_host_file = self.not_in_host_file(self.host)
|
||||||
|
|
||||||
|
if C.HOST_KEY_CHECKING and not_in_host_file:
|
||||||
|
# lock around the initial SSH connectivity so the user prompt about whether to add
|
||||||
|
# the host to known hosts is not intermingled with multiprocess output.
|
||||||
|
KEY_LOCK = self.runner.lockfile
|
||||||
|
fcntl.lockf(KEY_LOCK, fcntl.LOCK_EX)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Make sure stdin is a proper (pseudo) pty to avoid: tcgetattr errors
|
# Make sure stdin is a proper (pseudo) pty to avoid: tcgetattr errors
|
||||||
import pty
|
import pty
|
||||||
|
@ -161,6 +187,12 @@ class Connection(object):
|
||||||
elif p.poll() is not None:
|
elif p.poll() is not None:
|
||||||
break
|
break
|
||||||
stdin.close() # close stdin after we read from stdout (see also issue #848)
|
stdin.close() # close stdin after we read from stdout (see also issue #848)
|
||||||
|
|
||||||
|
if C.HOST_KEY_CHECKING and not_in_host_file:
|
||||||
|
# lock around the initial SSH connectivity so the user prompt about whether to add
|
||||||
|
# the host to known hosts is not intermingled with multiprocess output.
|
||||||
|
KEY_LOCK = self.runner.lockfile
|
||||||
|
fcntl.lockf(KEY_LOCK, fcntl.LOCK_EX)
|
||||||
|
|
||||||
if p.returncode != 0 and stderr.find('Bad configuration option: ControlPersist') != -1:
|
if p.returncode != 0 and stderr.find('Bad configuration option: ControlPersist') != -1:
|
||||||
raise errors.AnsibleError('using -c ssh on certain older ssh versions may not support ControlPersist, set ANSIBLE_SSH_ARGS="" (or ansible_ssh_args in the config file) before running again')
|
raise errors.AnsibleError('using -c ssh on certain older ssh versions may not support ControlPersist, set ANSIBLE_SSH_ARGS="" (or ansible_ssh_args in the config file) before running again')
|
||||||
|
|
Loading…
Reference in a new issue