issue #301: correct remote_tmp evaluation context.

Vanilla Ansible expands remote_tmp variables in the context of the login
account, not any become_user account.
pull/322/head
David Wilson 6 years ago
parent de0d526487
commit a8e4dcc98d

@ -348,10 +348,14 @@ class Connection(ansible.plugins.connection.ConnectionBase):
#: presently always the connection multiplexer process. #: presently always the connection multiplexer process.
parent = None parent = None
#: mitogen.parent.Context connected to the target user account on the #: mitogen.parent.Context for the target account on the target, possibly
#: target machine (i.e. possibly via sudo). #: reached via become.
context = None context = None
#: mitogen.parent.Context for the login account on the target. This is
#: always the login account, even when become=True.
login_context = None
#: mitogen.parent.Context connected to the fork parent process in the #: mitogen.parent.Context connected to the fork parent process in the
#: target user account. #: target user account.
fork_context = None fork_context = None
@ -529,6 +533,11 @@ class Connection(ansible.plugins.connection.ConnectionBase):
raise ansible.errors.AnsibleConnectionFailure(dct['msg']) raise ansible.errors.AnsibleConnectionFailure(dct['msg'])
self.context = dct['context'] self.context = dct['context']
if self._play_context.become:
self.login_context = dct['via']
else:
self.login_context = self.context
self.fork_context = dct['init_child_result']['fork_context'] self.fork_context = dct['init_child_result']['fork_context']
self.home_dir = dct['init_child_result']['home_dir'] self.home_dir = dct['init_child_result']['home_dir']
@ -546,6 +555,8 @@ class Connection(ansible.plugins.connection.ConnectionBase):
) )
self.context = None self.context = None
self.fork_context = None
self.login_context = None
if self.broker and not new_task: if self.broker and not new_task:
self.broker.shutdown() self.broker.shutdown()
self.broker.join() self.broker.join()
@ -556,11 +567,18 @@ class Connection(ansible.plugins.connection.ConnectionBase):
""" """
Start a function call to the target. Start a function call to the target.
:param bool use_login_context:
If present and :data:`True`, send the call to the login account
context rather than the optional become user context.
:returns: :returns:
mitogen.core.Receiver that receives the function call result. mitogen.core.Receiver that receives the function call result.
""" """
self._connect() self._connect()
return self.context.call_async(func, *args, **kwargs) if kwargs.pop('use_login_context', None):
call_context = self.login_context
else:
call_context = self.context
return call_context.call_async(func, *args, **kwargs)
def call(self, func, *args, **kwargs): def call(self, func, *args, **kwargs):
""" """

@ -200,9 +200,10 @@ class ActionModuleMixin(ansible.plugins.action.ActionBase):
# _make_tmp_path() is basically a global stashed away as Shell.tmpdir. # _make_tmp_path() is basically a global stashed away as Shell.tmpdir.
# The copy action plugin violates layering and grabs this attribute # The copy action plugin violates layering and grabs this attribute
# directly. # directly.
self._connection._shell.tmpdir = self.call( self._connection._shell.tmpdir = self._connection.call(
ansible_mitogen.target.make_temp_directory, ansible_mitogen.target.make_temp_directory,
base_dir=self._get_remote_tmp(), base_dir=self._get_remote_tmp(),
use_login_context=True,
) )
LOG.debug('Temporary directory: %r', self._connection._shell.tmpdir) LOG.debug('Temporary directory: %r', self._connection._shell.tmpdir)
self._cleanup_remote_tmp = True self._cleanup_remote_tmp = True

@ -267,6 +267,7 @@ class ContextService(mitogen.service.Service):
{ {
'context': mitogen.core.Context or None, 'context': mitogen.core.Context or None,
'via': mitogen.core.Context or None,
'init_child_result': { 'init_child_result': {
'fork_context': mitogen.core.Context, 'fork_context': mitogen.core.Context,
'home_dir': str or None, 'home_dir': str or None,
@ -308,6 +309,7 @@ class ContextService(mitogen.service.Service):
self._refs_by_context[context] = 0 self._refs_by_context[context] = 0
return { return {
'context': context, 'context': context,
'via': via,
'init_child_result': init_child_result, 'init_child_result': init_child_result,
'msg': None, 'msg': None,
} }

@ -2,16 +2,54 @@
- name: integration/action/make_tmp_path.yml - name: integration/action/make_tmp_path.yml
hosts: test-targets hosts: test-targets
any_errors_fatal: true any_errors_fatal: true
gather_facts: true
tasks: tasks:
- name: "Find out root's homedir."
# Runs first because it blats regular Ansible facts with junk, so
# non-become run fixes that up.
setup: gather_subset=min
become: true
register: root_facts
- name: "Find regular homedir"
setup: gather_subset=min
register: user_facts
#
# non-become
#
- action_passthrough:
method: _make_tmp_path
register: out
- assert:
# This string must match ansible.cfg::remote_tmp
that: out.result.startswith("{{user_facts.ansible_facts.ansible_user_dir}}/.ansible/mitogen-tests/")
- stat:
path: "{{out.result}}"
register: st
- assert:
that: st.stat.exists and st.stat.isdir and st.stat.mode == "0700"
- file:
path: "{{out.result}}"
state: absent
#
# become. make_tmp_path() must evaluate HOME in the context of the SSH
# user, not the become user.
#
- action_passthrough: - action_passthrough:
method: _make_tmp_path method: _make_tmp_path
register: out register: out
become: true
- assert: - assert:
# This string must match ansible.cfg::remote_tmp # This string must match ansible.cfg::remote_tmp
that: out.result.startswith("{{ansible_user_dir}}/.ansible/mitogen-tests/") that: out.result.startswith("{{user_facts.ansible_facts.ansible_user_dir}}/.ansible/mitogen-tests/")
- stat: - stat:
path: "{{out.result}}" path: "{{out.result}}"

@ -4,27 +4,46 @@
- name: integration/action/remote_expand_user.yml - name: integration/action/remote_expand_user.yml
hosts: test-targets hosts: test-targets
any_errors_fatal: true any_errors_fatal: true
gather_facts: true
tasks: tasks:
- name: "Find out root's homedir."
# Runs first because it blats regular Ansible facts with junk, so
# non-become run fixes that up.
setup: gather_subset=min
become: true
register: root_facts
# Expand ~/foo - name: "Find regular homedir"
- action_passthrough: setup: gather_subset=min
register: user_facts
- name: "Expand ~/foo"
action_passthrough:
method: _remote_expand_user method: _remote_expand_user
args: ['~/foo'] args: ['~/foo']
register: out register: out
- assert: - assert:
that: out.result == '{{ansible_user_dir}}/foo' that: out.result == '{{user_facts.ansible_facts.ansible_user_dir}}/foo'
- name: "Expand ~/foo with become active. ~ is become_user's home."
action_passthrough:
method: _remote_expand_user
args: ['~/foo']
register: out
become: true
- assert:
that: out.result == '{{root_facts.ansible_facts.ansible_user_dir}}/foo'
# Expand ~user/foo - name: "Expand ~user/foo"
- action_passthrough: action_passthrough:
method: _remote_expand_user method: _remote_expand_user
args: ['~{{ansible_user_id}}/foo'] args: ['~{{ansible_user_id}}/foo']
register: out register: out
- assert: - assert:
that: out.result == '{{ansible_user_dir}}/foo' that: out.result == '{{user_facts.ansible_facts.ansible_user_dir}}/foo'
# Expanding $HOME/foo has no effect. - name: "Expanding $HOME/foo has no effect."
- action_passthrough: action_passthrough:
method: _remote_expand_user method: _remote_expand_user
args: ['$HOME/foo'] args: ['$HOME/foo']
register: out register: out

Loading…
Cancel
Save