From 316284c56b2f5eab18563a13694e98fc86b68894 Mon Sep 17 00:00:00 2001 From: James Cammarata Date: Tue, 17 Mar 2015 10:35:24 -0500 Subject: [PATCH] Making blocks support become, and cleaning up sudo/su references --- v2/ansible/executor/connection_info.py | 7 +++++-- v2/ansible/executor/task_executor.py | 2 +- v2/ansible/playbook/become.py | 9 +++++++++ v2/ansible/playbook/block.py | 24 +++++++++++++++++------- v2/ansible/plugins/action/assemble.py | 2 +- v2/ansible/plugins/action/copy.py | 2 +- v2/ansible/plugins/action/fetch.py | 2 +- v2/ansible/plugins/action/script.py | 3 +-- v2/ansible/plugins/action/template.py | 8 ++++---- v2/ansible/plugins/action/unarchive.py | 2 +- v2/samples/test_become.yml | 4 +++- 11 files changed, 44 insertions(+), 21 deletions(-) diff --git a/v2/ansible/executor/connection_info.py b/v2/ansible/executor/connection_info.py index b918dc6b214..0ae51e6b612 100644 --- a/v2/ansible/executor/connection_info.py +++ b/v2/ansible/executor/connection_info.py @@ -157,10 +157,13 @@ class ConnectionInformation: new_info.copy(self) for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'environment', 'no_log'): + attr_val = None if hasattr(task, attr): attr_val = getattr(task, attr) - if attr_val: - setattr(new_info, attr, attr_val) + if task._block and hasattr(task._block, attr) and not attr_val: + attr_val = getattr(task._block, attr) + if attr_val: + setattr(new_info, attr, attr_val) return new_info diff --git a/v2/ansible/executor/task_executor.py b/v2/ansible/executor/task_executor.py index bad47279a5e..7eaba0061ef 100644 --- a/v2/ansible/executor/task_executor.py +++ b/v2/ansible/executor/task_executor.py @@ -382,7 +382,7 @@ class TaskExecutor: self._connection_info.password = this_info.get('ansible_ssh_pass', self._connection_info.password) self._connection_info.private_key_file = this_info.get('ansible_ssh_private_key_file', self._connection_info.private_key_file) self._connection_info.connection = this_info.get('ansible_connection', self._connection_info.connection) - self._connection_info.sudo_pass = this_info.get('ansible_sudo_pass', self._connection_info.sudo_pass) + self._connection_info.become_pass = this_info.get('ansible_sudo_pass', self._connection_info.become_pass) if self._connection_info.remote_addr in ('127.0.0.1', 'localhost'): self._connection_info.connection = 'local' diff --git a/v2/ansible/playbook/become.py b/v2/ansible/playbook/become.py index 6ac1d2bad98..0b0ad101760 100644 --- a/v2/ansible/playbook/become.py +++ b/v2/ansible/playbook/become.py @@ -19,6 +19,7 @@ from __future__ import (absolute_import, division, print_function) __metaclass__ = type +from ansible import constants as C from ansible.errors import AnsibleError, AnsibleParserError from ansible.playbook.attribute import Attribute, FieldAttribute #from ansible.utils.display import deprecated @@ -85,4 +86,12 @@ class Become: #deprecated("Instead of su/su_user, use become/become_user and set become_method to 'su' (default is sudo)") + # if we are becoming someone else, but some fields are unset, + # make sure they're initialized to the default config values + if ds.get('become', False): + if ds.get('become_method', None) is None: + ds['become_method'] = C.DEFAULT_BECOME_METHOD + if ds.get('become_user', None) is None: + ds['become_user'] = C.DEFAULT_BECOME_USER + return ds diff --git a/v2/ansible/playbook/block.py b/v2/ansible/playbook/block.py index 49f65a15349..fa67b6ae1b9 100644 --- a/v2/ansible/playbook/block.py +++ b/v2/ansible/playbook/block.py @@ -21,13 +21,13 @@ __metaclass__ = type from ansible.playbook.attribute import Attribute, FieldAttribute from ansible.playbook.base import Base -#from ansible.playbook.become import Become +from ansible.playbook.become import Become from ansible.playbook.conditional import Conditional from ansible.playbook.helpers import load_list_of_tasks from ansible.playbook.role import Role from ansible.playbook.taggable import Taggable -class Block(Base, Conditional, Taggable): +class Block(Base, Become, Conditional, Taggable): _block = FieldAttribute(isa='list', default=[]) _rescue = FieldAttribute(isa='list', default=[]) @@ -71,16 +71,18 @@ class Block(Base, Conditional, Taggable): If a simple task is given, an implicit block for that single task is created, which goes in the main portion of the block ''' + is_block = False for attr in ('block', 'rescue', 'always'): if attr in ds: is_block = True break + if not is_block: if isinstance(ds, list): - return dict(block=ds) + return super(Block, self).munge(dict(block=ds)) else: - return dict(block=[ds]) + return super(Block, self).munge(dict(block=[ds])) return super(Block, self).munge(ds) @@ -166,7 +168,11 @@ class Block(Base, Conditional, Taggable): a task we don't want to include the attribute list of tasks. ''' - data = dict(when=self.when) + data = dict() + for attr in self._get_base_attributes(): + if attr not in ('block', 'rescue', 'always'): + data[attr] = getattr(self, attr) + data['dep_chain'] = self._dep_chain if self._role is not None: @@ -184,8 +190,12 @@ class Block(Base, Conditional, Taggable): from ansible.playbook.task import Task - # unpack the when attribute, which is the only one we want - self.when = data.get('when') + # we don't want the full set of attributes (the task lists), as that + # would lead to a serialize/deserialize loop + for attr in self._get_base_attributes(): + if attr in data and attr not in ('block', 'rescue', 'always'): + setattr(self, attr, data.get(attr)) + self._dep_chain = data.get('dep_chain', []) # if there was a serialized role, unpack it too diff --git a/v2/ansible/plugins/action/assemble.py b/v2/ansible/plugins/action/assemble.py index 1ae8be02039..b1bdc06c6d3 100644 --- a/v2/ansible/plugins/action/assemble.py +++ b/v2/ansible/plugins/action/assemble.py @@ -117,7 +117,7 @@ class ActionModule(ActionBase): xfered = self._transfer_data('src', resultant) # fix file permissions when the copy is done as a different user - if self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root': + if self._connection_info.become and self._connection_info.become_user != 'root': self._remote_chmod('a+r', xfered, tmp) # run the copy module diff --git a/v2/ansible/plugins/action/copy.py b/v2/ansible/plugins/action/copy.py index 46cb8955026..088a806b61b 100644 --- a/v2/ansible/plugins/action/copy.py +++ b/v2/ansible/plugins/action/copy.py @@ -231,7 +231,7 @@ class ActionModule(ActionBase): self._remove_tempfile_if_content_defined(content, content_tempfile) # fix file permissions when the copy is done as a different user - if (self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root') and not raw: + if (self._connection_info.become and self._connection_info.become_user != 'root': self._remote_chmod('a+r', tmp_src, tmp) if raw: diff --git a/v2/ansible/plugins/action/fetch.py b/v2/ansible/plugins/action/fetch.py index 9bd73136b48..e63fd88ea5c 100644 --- a/v2/ansible/plugins/action/fetch.py +++ b/v2/ansible/plugins/action/fetch.py @@ -57,7 +57,7 @@ class ActionModule(ActionBase): # use slurp if sudo and permissions are lacking remote_data = None - if remote_checksum in ('1', '2') or self._connection_info.sudo: + if remote_checksum in ('1', '2') or self._connection_info.become: slurpres = self._execute_module(module_name='slurp', module_args=dict(src=source), tmp=tmp) if slurpres.get('rc') == 0: if slurpres['encoding'] == 'base64': diff --git a/v2/ansible/plugins/action/script.py b/v2/ansible/plugins/action/script.py index 6e8c1e1b9a4..21a9f41c59b 100644 --- a/v2/ansible/plugins/action/script.py +++ b/v2/ansible/plugins/action/script.py @@ -74,8 +74,7 @@ class ActionModule(ActionBase): sudoable = True # set file permissions, more permissive when the copy is done as a different user - if ((self._connection_info.sudo and self._connection_info.sudo_user != 'root') or - (self._connection_info.su and self._connection_info.su_user != 'root')): + if self._connection_info.become and self._connection_info.become_user != 'root': chmod_mode = 'a+rx' sudoable = False else: diff --git a/v2/ansible/plugins/action/template.py b/v2/ansible/plugins/action/template.py index 372c07544d3..1f7a6955a32 100644 --- a/v2/ansible/plugins/action/template.py +++ b/v2/ansible/plugins/action/template.py @@ -26,8 +26,6 @@ class ActionModule(ActionBase): TRANSFERS_FILES = True - - def get_checksum(self, tmp, dest, try_directory=False, source=None): remote_checksum = self._remote_checksum(tmp, dest) @@ -92,7 +90,9 @@ class ActionModule(ActionBase): # Expand any user home dir specification dest = self._remote_expand_user(dest, tmp) + directory_prepended = False if dest.endswith("/"): # CCTODO: Fix path for Windows hosts. + directory_prepended = True base = os.path.basename(source) dest = os.path.join(dest, base) @@ -105,7 +105,7 @@ class ActionModule(ActionBase): except Exception, e: return dict(failed=True, msg=type(e).__name__ + ": " + str(e)) - local_checksum = utils.checksum_s(resultant) + local_checksum = checksum_s(resultant) remote_checksum = self.get_checksum(tmp, dest, not directory_prepended, source=source) if isinstance(remote_checksum, dict): # Error from remote_checksum is a dict. Valid return is a str @@ -129,7 +129,7 @@ class ActionModule(ActionBase): xfered = self._transfer_data(self._shell.join_path(tmp, 'source'), resultant) # fix file permissions when the copy is done as a different user - if self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root': + if self._connection_info.become and self._connection_info.become_user != 'root': self._remote_chmod('a+r', xfered, tmp) # run the copy module diff --git a/v2/ansible/plugins/action/unarchive.py b/v2/ansible/plugins/action/unarchive.py index fab0843e9fe..f99d7e28e64 100644 --- a/v2/ansible/plugins/action/unarchive.py +++ b/v2/ansible/plugins/action/unarchive.py @@ -81,7 +81,7 @@ class ActionModule(ActionBase): # handle check mode client side # fix file permissions when the copy is done as a different user if copy: - if self._connection_info.sudo and self._connection_info.sudo_user != 'root' or self._connection_info.su and self._connection_info.su_user != 'root': + if self._connection_info.become and self._connection_info.become_user != 'root': # FIXME: noop stuff needs to be reworked #if not self.runner.noop_on_check(task_vars): # self.runner._remote_chmod(conn, 'a+r', tmp_src, tmp) diff --git a/v2/samples/test_become.yml b/v2/samples/test_become.yml index 8e753beade3..4b02563ca79 100644 --- a/v2/samples/test_become.yml +++ b/v2/samples/test_become.yml @@ -3,4 +3,6 @@ tasks: - command: whoami become_user: testing - become_method: su + - block: + - command: whoami + become_user: testing