issue #177: fetch and cache HOME value during connection setup.

This ensures only 1 roundtrip is required for every invocation of
_remote_expand_user().
This commit is contained in:
David Wilson 2018-04-01 15:54:17 +01:00
parent 772e229b7d
commit 6eed3aa1fa
3 changed files with 38 additions and 10 deletions

View File

@ -82,6 +82,9 @@ class Connection(ansible.plugins.connection.ConnectionBase):
#: Set to 'mitogen_ssh_discriminator' by on_action_run()
mitogen_ssh_discriminator = None
#: Set after connection to the target context's home directory.
_homedir = None
def __init__(self, play_context, new_stdin, original_transport, **kwargs):
assert ansible_mitogen.process.MuxProcess.unix_listener_path, (
'The "mitogen" connection plug-in may only be instantiated '
@ -125,6 +128,11 @@ class Connection(ansible.plugins.connection.ConnectionBase):
'sudo'
)
@property
def homedir(self):
self._connect()
return self._homedir
@property
def connected(self):
return self.broker is not None
@ -232,18 +240,20 @@ class Connection(ansible.plugins.connection.ConnectionBase):
if self.original_transport == 'local':
if self._play_context.become:
self.context = self._connect_sudo(python_path=sys.executable)
self.context, self._homedir = self._connect_sudo(
python_path=sys.executable
)
else:
self.context = self._connect_local()
self.context, self._homedir = self._connect_local()
return
if self.original_transport == 'docker':
self.host = self._connect_docker()
self.host, self._homedir = self._connect_docker()
elif self.original_transport == 'ssh':
self.host = self._connect_ssh()
self.host, self._homedir = self._connect_ssh()
if self._play_context.become:
self.context = self._connect_sudo(via=self.host)
self.context, self._homedir = self._connect_sudo(via=self.host)
else:
self.context = self.host

View File

@ -272,10 +272,19 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
Replace the base implementation's attempt to emulate
os.path.expanduser() with an actual call to os.path.expanduser().
"""
LOG.debug('_remove_expand_user(%r, sudoable=%r)', path, sudoable)
LOG.debug('_remote_expand_user(%r, sudoable=%r)', path, sudoable)
if not path.startswith('~'):
# /home/foo -> /home/foo
return path
if path == '~':
# ~ -> /home/dmw
return self._connection.homedir
if path.startswith('~/'):
# ~/.ansible -> /home/dmw/.ansible
return os.path.join(self._connection.homedir, path[2:])
if path.startswith('~'):
path = self.call(os.path.expanduser, path)
return path
# ~root/.ansible -> /root/.ansible
return self.call(os.path.expanduser, path)
def _execute_module(self, module_name=None, module_args=None, tmp=None,
task_vars=None, persist_files=False,

View File

@ -28,6 +28,7 @@
from __future__ import absolute_import
import logging
import os.path
import zlib
import mitogen
@ -62,7 +63,13 @@ class ContextService(mitogen.service.DeduplicatingService):
existing connection, but popped from the list of arguments passed to
the connection method.
:returns mitogen.master.Context:
:returns tuple:
Tuple of `(context, home_dir)`, where:
* `context` is the mitogen.master.Context referring to the target
context.
* `home_dir` is a cached copy of the remote directory.
mitogen.master.Context:
Corresponding Context instance.
"""
handle = 500
@ -74,7 +81,9 @@ class ContextService(mitogen.service.DeduplicatingService):
def get_response(self, args):
args.pop('discriminator', None)
method = getattr(self.router, args.pop('method'))
return method(**args)
context = method(**args)
home_dir = context.call(os.path.expanduser, '~')
return context, home_dir
class FileService(mitogen.service.Service):