Fix environment setting and inheritence

Fixes #11401
pull/11683/head
James Cammarata 9 years ago
parent 29a9b8ab7d
commit 66a8864ae9

@ -49,7 +49,7 @@ class Base:
# vars and flags # vars and flags
_vars = FieldAttribute(isa='dict', default=dict()) _vars = FieldAttribute(isa='dict', default=dict())
_environment = FieldAttribute(isa='dict', default=dict()) _environment = FieldAttribute(isa='list', default=[])
_no_log = FieldAttribute(isa='bool', default=False) _no_log = FieldAttribute(isa='bool', default=False)
def __init__(self): def __init__(self):

@ -301,6 +301,18 @@ class Block(Base, Become, Conditional, Taggable):
return value return value
def _get_attr_environment(self):
'''
Override for the 'tags' getattr fetcher, used from Base.
'''
environment = self._attributes['tags']
if environment is None:
environment = dict()
environment = self._get_parent_attribute('environment', extend=True)
return environment
def filter_tagged_tasks(self, play_context, all_vars): def filter_tagged_tasks(self, play_context, all_vars):
''' '''
Creates a new block, with task lists filtered based on the tags contained Creates a new block, with task lists filtered based on the tags contained

@ -217,7 +217,6 @@ class PlayContext(Base):
# non connection related # non connection related
self.no_log = play.no_log self.no_log = play.no_log
self.environment = play.environment
if play.force_handlers is not None: if play.force_handlers is not None:
self.force_handlers = play.force_handlers self.force_handlers = play.force_handlers
@ -299,7 +298,7 @@ class PlayContext(Base):
# loop through a subset of attributes on the task object and set # loop through a subset of attributes on the task object and set
# connection fields based on their values # connection fields based on their values
for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'environment', 'no_log'): for attr in ('connection', 'remote_user', 'become', 'become_user', 'become_pass', 'become_method', 'no_log'):
if hasattr(task, attr): if hasattr(task, attr):
attr_val = getattr(task, attr) attr_val = getattr(task, attr)
if attr_val is not None: if attr_val is not None:

@ -34,7 +34,6 @@ from ansible.playbook.block import Block
from ansible.playbook.conditional import Conditional from ansible.playbook.conditional import Conditional
from ansible.playbook.role import Role from ansible.playbook.role import Role
from ansible.playbook.taggable import Taggable from ansible.playbook.taggable import Taggable
from ansible.utils.vars import combine_vars
__all__ = ['Task'] __all__ = ['Task']
@ -293,25 +292,21 @@ class Task(Base, Conditional, Taggable, Become):
if self._task_include: if self._task_include:
self._task_include.set_loader(loader) self._task_include.set_loader(loader)
def _get_parent_attribute(self, attr, extend=False, combine=False): def _get_parent_attribute(self, attr, extend=False):
''' '''
Generic logic to get the attribute or parent attribute for a task value. Generic logic to get the attribute or parent attribute for a task value.
''' '''
value = self._attributes[attr] value = self._attributes[attr]
if self._block and (value is None or extend or combine): if self._block and (value is None or extend):
parent_value = getattr(self._block, attr) parent_value = getattr(self._block, attr)
if extend: if extend:
value = self._extend_value(value, parent_value) value = self._extend_value(value, parent_value)
elif combine and isinstance(parent_value, dict) and isinstance(value, dict):
value = combine_vars(parent_value, value)
else: else:
value = parent_value value = parent_value
if self._task_include and (value is None or extend or combine): if self._task_include and (value is None or extend):
parent_value = getattr(self._task_include, attr) parent_value = getattr(self._task_include, attr)
if extend: if extend:
value = self._extend_value(value, parent_value) value = self._extend_value(value, parent_value)
elif combine:
value = combine_vars(parent_value, value)
else: else:
value = parent_value value = parent_value
return value return value
@ -324,7 +319,7 @@ class Task(Base, Conditional, Taggable, Become):
if environment is None: if environment is None:
environment = dict() environment = dict()
environment = self._get_parent_attribute('environment', combine=True) environment = self._get_parent_attribute('environment', extend=True)
return environment return environment

@ -81,11 +81,20 @@ class ActionBase:
Builds the environment string to be used when executing the remote task. Builds the environment string to be used when executing the remote task.
''' '''
if self._task.environment: final_environment = dict()
if type(self._task.environment) != dict: if self._task.environment is not None:
raise errors.AnsibleError("environment must be a dictionary, received %s" % self._task.environment) environments = self._task.environment
if not isinstance(environments, list):
return self._connection._shell.env_prefix(**self._task.environment) environments = [ environments ]
for environment in environments:
if type(environment) != dict:
raise errors.AnsibleError("environment must be a dictionary, received %s" % environment)
# very deliberatly using update here instead of combine_vars, as
# these environment settings should not need to merge sub-dicts
final_environment.update(environment)
return self._connection._shell.env_prefix(**final_environment)
def _early_needs_tmp_path(self): def _early_needs_tmp_path(self):
''' '''

@ -73,7 +73,6 @@ class TestPlayContext(unittest.TestCase):
mock_play.become_method = 'mock' mock_play.become_method = 'mock'
mock_play.become_user = 'mockroot' mock_play.become_user = 'mockroot'
mock_play.no_log = True mock_play.no_log = True
mock_play.environment = dict(mock='mockenv')
play_context = PlayContext(play=mock_play, options=options) play_context = PlayContext(play=mock_play, options=options)
self.assertEqual(play_context.connection, 'mock') self.assertEqual(play_context.connection, 'mock')
@ -81,7 +80,6 @@ class TestPlayContext(unittest.TestCase):
self.assertEqual(play_context.password, '') self.assertEqual(play_context.password, '')
self.assertEqual(play_context.port, 1234) self.assertEqual(play_context.port, 1234)
self.assertEqual(play_context.no_log, True) self.assertEqual(play_context.no_log, True)
self.assertEqual(play_context.environment, dict(mock="mockenv"))
self.assertEqual(play_context.become, True) self.assertEqual(play_context.become, True)
self.assertEqual(play_context.become_method, "mock") self.assertEqual(play_context.become_method, "mock")
self.assertEqual(play_context.become_user, "mockroot") self.assertEqual(play_context.become_user, "mockroot")
@ -94,7 +92,6 @@ class TestPlayContext(unittest.TestCase):
mock_task.become_user = 'mocktaskroot' mock_task.become_user = 'mocktaskroot'
mock_task.become_pass = 'mocktaskpass' mock_task.become_pass = 'mocktaskpass'
mock_task.no_log = False mock_task.no_log = False
mock_task.environment = dict(mock='mocktaskenv')
mock_host = MagicMock() mock_host = MagicMock()
mock_host.get_vars.return_value = dict( mock_host.get_vars.return_value = dict(
@ -108,7 +105,6 @@ class TestPlayContext(unittest.TestCase):
self.assertEqual(play_context.remote_user, 'mocktask') self.assertEqual(play_context.remote_user, 'mocktask')
self.assertEqual(play_context.port, 4321) self.assertEqual(play_context.port, 4321)
self.assertEqual(play_context.no_log, False) self.assertEqual(play_context.no_log, False)
self.assertEqual(play_context.environment, dict(mock="mocktaskenv"))
self.assertEqual(play_context.become, True) self.assertEqual(play_context.become, True)
self.assertEqual(play_context.become_method, "mocktask") self.assertEqual(play_context.become_method, "mocktask")
self.assertEqual(play_context.become_user, "mocktaskroot") self.assertEqual(play_context.become_user, "mocktaskroot")

Loading…
Cancel
Save