diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py index f5ea8aeb797..db46a25474f 100644 --- a/lib/ansible/playbook/play_context.py +++ b/lib/ansible/playbook/play_context.py @@ -134,6 +134,18 @@ SU_PROMPT_LOCALIZATIONS = [ '密碼', ] +TASK_ATTRIBUTE_OVERRIDES = ( + 'become', + 'become_user', + 'become_pass', + 'become_method', + 'connection', + 'delegate_to', + 'no_log', + 'remote_user', +) + + class PlayContext(Base): ''' @@ -285,7 +297,7 @@ class PlayContext(Base): # loop through a subset of attributes on the task object and set # connection fields based on their values - for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'no_log'): + for attr in TASK_ATTRIBUTE_OVERRIDES: if hasattr(task, attr): attr_val = getattr(task, attr) if attr_val is not None: diff --git a/lib/ansible/plugins/action/synchronize.py b/lib/ansible/plugins/action/synchronize.py index 031a2b0e977..11171d3e03e 100644 --- a/lib/ansible/plugins/action/synchronize.py +++ b/lib/ansible/plugins/action/synchronize.py @@ -75,13 +75,10 @@ class ActionModule(ActionBase): original_transport = task_vars.get('ansible_connection') or self._play_context.connection transport_overridden = False - if task_vars.get('delegate_to') is None: - task_vars['delegate_to'] = '127.0.0.1' - # IF original transport is not local, override transport and disable sudo. - if original_transport != 'local': - task_vars['ansible_connection'] = 'local' - transport_overridden = True - self._play_context.become = False + try: + delegate_to = self._play_context.delegate_to + except (AttributeError, KeyError): + delegate_to = None use_ssh_args = self._task.args.pop('use_ssh_args', None) @@ -103,13 +100,15 @@ class ActionModule(ActionBase): # CHECK DELEGATE HOST INFO use_delegate = False - if dest_host == task_vars.get('delegate_to'): + if dest_host == delegate_to: # edge case: explicit delegate and dest_host are the same + # so we run rsync on the remote machine targetting its localhost + # (itself) dest_host = '127.0.0.1' use_delegate = True else: if 'hostvars' in task_vars: - if task_vars.get('delegate_to') in task_vars['hostvars'] and original_transport != 'local': + if delegate_to in task_vars['hostvars'] and original_transport != 'local': # use a delegate host instead of localhost use_delegate = True @@ -126,12 +125,19 @@ class ActionModule(ActionBase): # Delegate to localhost as the source of the rsync unless we've been # told (via delegate_to) that a different host is the source of the # rsync - if not use_delegate: + transport_overridden = False + if not use_delegate and original_transport != 'local': # Create a connection to localhost to run rsync on - ### FIXME: Do we have to dupe stdin or is this sufficient? new_stdin = self._connection._new_stdin new_connection = connection_loader.get('local', self._play_context, new_stdin) self._connection = new_connection + transport_overridden = True + ### FIXME: We think that this was here for v1 because the local + # connection didn't support sudo. In v2 it does so we think it's + # safe to remove this now. + + # Also disable sudo + #self._play_context.become = False # MUNGE SRC AND DEST PER REMOTE_HOST INFO src = self._task.args.get('src', None) @@ -140,10 +146,11 @@ class ActionModule(ActionBase): user = None if boolean(task_vars.get('set_remote_user', 'yes')): + if use_delegate: + user = task_vars['hostvars'][delegate_to].get('ansible_ssh_user') + if not use_delegate or not user: user = task_vars.get('ansible_ssh_user') or self._play_context.remote_user - elif use_delegate: - user = task_vars['hostvars'][task_vars.get('delegate_to')].get('ansible_ssh_user') if use_delegate: private_key = task_vars.get('ansible_ssh_private_key_file') or self._play_context.private_key_file