mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Use a -short- custom hash for controlpersist path by default (#20843)
* A method to validate and alter the ssh control path automatically. * First tries %C to use the shortened hash * On further failure, it removes section by section from the original path * Fix hostname * Implement bcoca's suggested changes * Remove unused option * Remove unused class var * Use to_string to avoid unicode error * Switch from to_text to to_bytes * Update the example config for the new controlpath feature
This commit is contained in:
parent
6244271d46
commit
ac78347f2b
3 changed files with 29 additions and 10 deletions
|
@ -310,16 +310,14 @@
|
||||||
# control_path_dir = /tmp/.ansible/cp
|
# control_path_dir = /tmp/.ansible/cp
|
||||||
#control_path_dir = ~/.ansible/cp
|
#control_path_dir = ~/.ansible/cp
|
||||||
|
|
||||||
# The path to use for the ControlPath sockets. This defaults to
|
# The path to use for the ControlPath sockets. This defaults to a hashed string of the hostname,
|
||||||
# "%(directory)s/ansible-ssh-%%h-%%p-%%r", however on some systems with
|
# port and username (empty string in the config). The hash mitigates a common problem users
|
||||||
# very long hostnames or very long path names (caused by long user names or
|
# found with long hostames and the conventional %(directory)s/ansible-ssh-%%h-%%p-%%r format.
|
||||||
# deeply nested home directories) this can exceed the character limit on
|
# In those cases, a "too long for Unix domain socket" ssh error would occur.
|
||||||
# file socket names (108 characters for most platforms). In that case, you
|
|
||||||
# may wish to shorten the string below.
|
|
||||||
#
|
#
|
||||||
# Example:
|
# Example:
|
||||||
# control_path = %(directory)s/%%h-%%r
|
# control_path = %(directory)s/%%h-%%r
|
||||||
#control_path = %(directory)s/ansible-ssh-%%h-%%p-%%r
|
#control_path =
|
||||||
|
|
||||||
# Enabling pipelining reduces the number of SSH operations required to
|
# Enabling pipelining reduces the number of SSH operations required to
|
||||||
# execute a module on the remote server. This can result in a significant
|
# execute a module on the remote server. This can result in a significant
|
||||||
|
|
|
@ -331,7 +331,7 @@ ANSIBLE_SSH_ARGS = get_config(p, 'ssh_connection', 'ssh_args', 'AN
|
||||||
# to .format() in the future. be sure to read this:
|
# to .format() in the future. be sure to read this:
|
||||||
# http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/ and understand
|
# http://lucumr.pocoo.org/2016/12/29/careful-with-str-format/ and understand
|
||||||
# that it may be a security risk to do so.
|
# that it may be a security risk to do so.
|
||||||
ANSIBLE_SSH_CONTROL_PATH = get_config(p, 'ssh_connection', 'control_path', 'ANSIBLE_SSH_CONTROL_PATH', u"%(directory)s/ansible-ssh-%%h-%%p-%%r")
|
ANSIBLE_SSH_CONTROL_PATH = get_config(p, 'ssh_connection', 'control_path', 'ANSIBLE_SSH_CONTROL_PATH', None)
|
||||||
ANSIBLE_SSH_CONTROL_PATH_DIR = get_config(p, 'ssh_connection', 'control_path_dir', 'ANSIBLE_SSH_CONTROL_PATH_DIR', u'~/.ansible/cp')
|
ANSIBLE_SSH_CONTROL_PATH_DIR = get_config(p, 'ssh_connection', 'control_path_dir', 'ANSIBLE_SSH_CONTROL_PATH_DIR', u'~/.ansible/cp')
|
||||||
ANSIBLE_SSH_PIPELINING = get_config(p, 'ssh_connection', 'pipelining', 'ANSIBLE_SSH_PIPELINING', False, value_type='boolean')
|
ANSIBLE_SSH_PIPELINING = get_config(p, 'ssh_connection', 'pipelining', 'ANSIBLE_SSH_PIPELINING', False, value_type='boolean')
|
||||||
ANSIBLE_SSH_RETRIES = get_config(p, 'ssh_connection', 'retries', 'ANSIBLE_SSH_RETRIES', 0, value_type='integer')
|
ANSIBLE_SSH_RETRIES = get_config(p, 'ssh_connection', 'retries', 'ANSIBLE_SSH_RETRIES', 0, value_type='integer')
|
||||||
|
|
|
@ -21,6 +21,7 @@ __metaclass__ = type
|
||||||
|
|
||||||
import errno
|
import errno
|
||||||
import fcntl
|
import fcntl
|
||||||
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import pty
|
import pty
|
||||||
import select
|
import select
|
||||||
|
@ -59,6 +60,10 @@ class Connection(ConnectionBase):
|
||||||
super(Connection, self).__init__(*args, **kwargs)
|
super(Connection, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.host = self._play_context.remote_addr
|
self.host = self._play_context.remote_addr
|
||||||
|
self.port = self._play_context.port
|
||||||
|
self.user = self._play_context.remote_user
|
||||||
|
self.control_path = C.ANSIBLE_SSH_CONTROL_PATH
|
||||||
|
self.control_path_dir = C.ANSIBLE_SSH_CONTROL_PATH_DIR
|
||||||
|
|
||||||
# The connection is created by running ssh/scp/sftp from the exec_command,
|
# The connection is created by running ssh/scp/sftp from the exec_command,
|
||||||
# put_file, and fetch_file methods, so we don't need to do any connection
|
# put_file, and fetch_file methods, so we don't need to do any connection
|
||||||
|
@ -67,6 +72,16 @@ class Connection(ConnectionBase):
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _create_control_path(host, port, user):
|
||||||
|
'''Make a hash for the controlpath based on con attributes'''
|
||||||
|
pstring = '%s-%s-%s' % (host, port, user)
|
||||||
|
m = hashlib.sha1()
|
||||||
|
m.update(to_bytes(pstring))
|
||||||
|
digest = m.hexdigest()
|
||||||
|
cpath = '%(directory)s/' + digest[:10]
|
||||||
|
return cpath
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _sshpass_available():
|
def _sshpass_available():
|
||||||
global SSHPASS_AVAILABLE
|
global SSHPASS_AVAILABLE
|
||||||
|
@ -228,7 +243,7 @@ class Connection(ConnectionBase):
|
||||||
self._persistent = True
|
self._persistent = True
|
||||||
|
|
||||||
if not controlpath:
|
if not controlpath:
|
||||||
cpdir = unfrackpath(C.ANSIBLE_SSH_CONTROL_PATH_DIR)
|
cpdir = unfrackpath(self.control_path_dir)
|
||||||
b_cpdir = to_bytes(cpdir, errors='surrogate_or_strict')
|
b_cpdir = to_bytes(cpdir, errors='surrogate_or_strict')
|
||||||
|
|
||||||
# The directory must exist and be writable.
|
# The directory must exist and be writable.
|
||||||
|
@ -236,7 +251,13 @@ class Connection(ConnectionBase):
|
||||||
if not os.access(b_cpdir, os.W_OK):
|
if not os.access(b_cpdir, os.W_OK):
|
||||||
raise AnsibleError("Cannot write to ControlPath %s" % to_native(cpdir))
|
raise AnsibleError("Cannot write to ControlPath %s" % to_native(cpdir))
|
||||||
|
|
||||||
b_args = (b"-o", b"ControlPath=" + to_bytes(C.ANSIBLE_SSH_CONTROL_PATH % dict(directory=cpdir), errors='surrogate_or_strict'))
|
if not self.control_path:
|
||||||
|
self.control_path = self._create_control_path(
|
||||||
|
self.host,
|
||||||
|
self.port,
|
||||||
|
self.user
|
||||||
|
)
|
||||||
|
b_args = (b"-o", b"ControlPath=" + to_bytes(self.control_path % dict(directory=cpdir), errors='surrogate_or_strict'))
|
||||||
self._add_args(b_command, b_args, u"found only ControlPersist; added ControlPath")
|
self._add_args(b_command, b_args, u"found only ControlPersist; added ControlPath")
|
||||||
|
|
||||||
# Finally, we add any caller-supplied extras.
|
# Finally, we add any caller-supplied extras.
|
||||||
|
|
Loading…
Reference in a new issue