From 2924f1c14a0cfa615cb533fc5955594bae926233 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 1 Nov 2013 12:44:56 +0000 Subject: [PATCH 01/30] Add a test case to check for proper env selection when passing `?env=foo`. Refs #8196. --- tests/integration/__init__.py | 4 ++++ tests/integration/files/file/prod/cheese | 1 + tests/integration/modules/cp.py | 18 ++++++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 tests/integration/files/file/prod/cheese diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index 3ba17c0fa8..a631cfc381 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -165,6 +165,10 @@ class TestDaemon(object): # Let's support runtime created files that can be used like: # salt://my-temp-file.txt TMP_STATE_TREE + ], + # Alternate root to test __env__ choices + 'prod': [ + os.path.join(FILES, 'file', 'prod') ] } self.master_opts['ext_pillar'].append( diff --git a/tests/integration/files/file/prod/cheese b/tests/integration/files/file/prod/cheese new file mode 100644 index 0000000000..3161cf5f73 --- /dev/null +++ b/tests/integration/files/file/prod/cheese @@ -0,0 +1 @@ +I could just fancy some cheese, Gromit. What do you say? Cheddar? Comte? diff --git a/tests/integration/modules/cp.py b/tests/integration/modules/cp.py index 6db8023280..f93cb9426a 100644 --- a/tests/integration/modules/cp.py +++ b/tests/integration/modules/cp.py @@ -277,6 +277,24 @@ class CPModuleTest(integration.ModuleCase): hashlib.md5(fn_.read()).hexdigest() ) + def test_get_file_from_env(self): + ''' + cp.get_file + ''' + tgt = os.path.join(integration.TMP, 'cheese') + self.run_function('cp.get_file', ['salt://cheese', tgt]) + with salt.utils.fopen(tgt, 'r') as cheese: + data = cheese.read() + self.assertIn('Gromit', data) + self.assertNotIn('Comte', data) + + self.run_function('cp.get_file', ['salt://cheese?env=prod', tgt]) + with salt.utils.fopen(tgt, 'r') as cheese: + data = cheese.read() + self.assertIn('Gromit', data) + self.assertIn('Comte', data) + + if __name__ == '__main__': from integration import run_tests From ec76b188b1e92799434188b4f4aa3910137e50c8 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 1 Nov 2013 19:36:09 +0000 Subject: [PATCH 02/30] Correctly trigger the issue reported on #8196. --- tests/integration/files/file/base/core.sls | 2 +- tests/integration/modules/cp.py | 31 +++++++++++++--------- tests/integration/modules/state.py | 19 +++++++++++-- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/tests/integration/files/file/base/core.sls b/tests/integration/files/file/base/core.sls index f7c5a2f2db..739a677627 100644 --- a/tests/integration/files/file/base/core.sls +++ b/tests/integration/files/file/base/core.sls @@ -1,4 +1,4 @@ -/testfile: +{{ salt['runtests_helpers.get_sys_temp_dir_for_path']('testfile') }}: file: - managed - source: salt://testfile diff --git a/tests/integration/modules/cp.py b/tests/integration/modules/cp.py index f93cb9426a..32680375cc 100644 --- a/tests/integration/modules/cp.py +++ b/tests/integration/modules/cp.py @@ -277,23 +277,30 @@ class CPModuleTest(integration.ModuleCase): hashlib.md5(fn_.read()).hexdigest() ) - def test_get_file_from_env(self): + def test_get_file_from_env_predifined(self): ''' cp.get_file ''' tgt = os.path.join(integration.TMP, 'cheese') - self.run_function('cp.get_file', ['salt://cheese', tgt]) - with salt.utils.fopen(tgt, 'r') as cheese: - data = cheese.read() - self.assertIn('Gromit', data) - self.assertNotIn('Comte', data) - - self.run_function('cp.get_file', ['salt://cheese?env=prod', tgt]) - with salt.utils.fopen(tgt, 'r') as cheese: - data = cheese.read() - self.assertIn('Gromit', data) - self.assertIn('Comte', data) + try: + self.run_function('cp.get_file', ['salt://cheese', tgt]) + with salt.utils.fopen(tgt, 'r') as cheese: + data = cheese.read() + self.assertIn('Gromit', data) + self.assertNotIn('Comte', data) + finally: + os.unlink(tgt) + def test_get_file_from_env_in_url(self): + tgt = os.path.join(integration.TMP, 'cheese') + try: + self.run_function('cp.get_file', ['salt://cheese?env=prod', tgt]) + with salt.utils.fopen(tgt, 'r') as cheese: + data = cheese.read() + self.assertIn('Gromit', data) + self.assertIn('Comte', data) + finally: + os.unlink(tgt) if __name__ == '__main__': diff --git a/tests/integration/modules/state.py b/tests/integration/modules/state.py index a17378cf4c..fad4b89577 100644 --- a/tests/integration/modules/state.py +++ b/tests/integration/modules/state.py @@ -24,9 +24,10 @@ class StateModuleTest(integration.ModuleCase, state.show_highstate ''' high = self.run_function('state.show_highstate') + destpath = os.path.join(integration.SYS_TMP_DIR, 'testfile') self.assertTrue(isinstance(high, dict)) - self.assertTrue('/testfile' in high) - self.assertEqual(high['/testfile']['__env__'], 'base') + self.assertTrue(destpath in high) + self.assertEqual(high[destpath]['__env__'], 'base') def test_show_lowstate(self): ''' @@ -362,6 +363,20 @@ fi 'The state "C" in sls syntax.badlist2 is not formed as a list' ]) + def test_get_file_from_env_in_top_match(self): + tgt = os.path.join(integration.SYS_TMP_DIR, 'prod-cheese-file') + try: + ret = self.run_function( + 'state.highstate', minion_tgt='sub_minion' + ) + self.assertSaltTrueReturn(ret) + with salt.utils.fopen(tgt, 'r') as cheese: + data = cheese.read() + self.assertIn('Gromit', data) + self.assertIn('Comte', data) + finally: + os.unlink(tgt) + if __name__ == '__main__': from integration import run_tests From e334e232d14e2d4e38174b05cd4f1f7d63af13e7 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 1 Nov 2013 21:06:15 +0000 Subject: [PATCH 03/30] Forgot to add the top file. --- tests/integration/files/file/prod/top.sls | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 tests/integration/files/file/prod/top.sls diff --git a/tests/integration/files/file/prod/top.sls b/tests/integration/files/file/prod/top.sls new file mode 100644 index 0000000000..bd9b07f9a8 --- /dev/null +++ b/tests/integration/files/file/prod/top.sls @@ -0,0 +1,4 @@ +prod: + 'G@role:sub': + - match: compound + - issue-8196 From 0a03ecc6bc36ac07e0fa156762f4e684278f2825 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 1 Nov 2013 21:46:03 +0000 Subject: [PATCH 04/30] Add required state file. --- tests/integration/files/file/prod/issue-8196.sls | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tests/integration/files/file/prod/issue-8196.sls diff --git a/tests/integration/files/file/prod/issue-8196.sls b/tests/integration/files/file/prod/issue-8196.sls new file mode 100644 index 0000000000..1a42ef6d80 --- /dev/null +++ b/tests/integration/files/file/prod/issue-8196.sls @@ -0,0 +1,3 @@ +{{ salt['runtests_helpers.get_sys_temp_dir_for_path']('prod-cheese-file') }}: + file.managed: + - source: salt://cheese From f4912bc797377da725bdef8150b53368ba5fd05f Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Fri, 1 Nov 2013 23:24:30 +0000 Subject: [PATCH 05/30] Log the env in use. --- salt/fileclient.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/salt/fileclient.py b/salt/fileclient.py index 330ee7c6f4..a516184e10 100644 --- a/salt/fileclient.py +++ b/salt/fileclient.py @@ -653,11 +653,18 @@ class RemoteClient(Client): hash_server = self.hash_file(path, env) if hash_local == hash_server: log.info( - 'Fetching file ** skipped **, ' - 'latest already in cache \'{0}\''.format(path)) + 'Fetching file from env {0!r}, ** skipped ** ' + 'latest already in cache {1!r}'.format( + env, path + ) + ) return dest2check - log.debug('Fetching file ** attempting ** \'{0}\''.format(path)) + log.debug( + 'Fetching file from env {0!r}, ** attempting ** {1!r}'.format( + env, path + ) + ) d_tries = 0 path = self._check_proto(path) load = {'path': path, @@ -722,7 +729,11 @@ class RemoteClient(Client): fn_.write(data) if fn_: fn_.close() - log.info('Fetching file ** done ** \'{0}\''.format(path)) + log.info( + 'Fetching file from env {0!r}, ** done ** {1!r}'.format( + env, path + ) + ) return dest def file_list(self, env='base', prefix=''): From 1d9e7442965093b98a694e1fca1f8371a874c1ce Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:17:40 +0000 Subject: [PATCH 06/30] Set the proper `__env__` as a function global when calling the state function. Fixes #8196. To achieve this we're making use of python's `with` context managers. Initially we check if the user is passing `env` from his state definition. If he his, then that's the `env` to use for as long as the state function is being executed. Passing `env` is also being deprecated, the users should use the more meaningful and unique `__env_`. If the user passed `__env__` in his state definition, that's the `env` to use, or, if no specific environment is being selected on the users state definition, then the default one, `base` is what will be used. This change makes it so that **any state module function** does not have to accept `__env__` as a keyword argument. --- salt/state.py | 30 ++++++++++++++++++++----- salt/utils/context.py | 52 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 salt/utils/context.py diff --git a/salt/state.py b/salt/state.py index c2234fc671..23680d72c8 100644 --- a/salt/state.py +++ b/salt/state.py @@ -30,6 +30,7 @@ import salt.pillar import salt.fileclient import salt.utils.event import salt.syspaths as syspaths +from salt.utils import context from salt._compat import string_types from salt.template import compile_template, compile_template_str from salt.exceptions import SaltReqTimeoutError, SaltException @@ -1260,12 +1261,31 @@ class State(object): test = sys.modules[self.states[cdata['full']].__module__].__opts__['test'] sys.modules[self.states[cdata['full']].__module__].__opts__['test'] = True try: - if 'kwargs' in cdata: - ret = self.states[cdata['full']]( - *cdata['args'], **cdata['kwargs']) + # Let's get a reference to the salt environment to use within this + # state call. + # + # If the state function accepts an 'env' keyword argument, it + # allows the state to be overridden(we look for that in cdata). If + # that's not found in cdata, we look for what we're being passed in + # the original data, namely, the special dunder __env__. If that's + # not found we default to 'base' + if cdata['kwargs'].get('env', None) is not None: + # User is using a deprecated env setting which was parsed by + # format_call + env = cdata['kwargs']['env'] + elif '__env__' in data: + # The user is passing an alternative environement using the + # proper keyword argument + env = data['__env__'] else: - ret = self.states[cdata['full']](*cdata['args']) - self.verify_ret(ret) + # Let's use the default environment + env = 'base' + + with context.state_call_context(self.states[cdata['full']], + __env__=env): + ret = self.states[cdata['full']](*cdata['args'], + **cdata['kwargs']) + self.verify_ret(ret) except Exception: trb = traceback.format_exc() ret = { diff --git a/salt/utils/context.py b/salt/utils/context.py new file mode 100644 index 0000000000..0cf342b5a3 --- /dev/null +++ b/salt/utils/context.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +''' + :codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)` + :copyright: © 2013 by the SaltStack Team, see AUTHORS for more details. + :license: Apache 2.0, see LICENSE for more details. + + + salt.utils.context + ~~~~~~~~~~~~~~~~~~ + + Context managers used throughout Salt's source code. +''' + +# Import python libs +from contextlib import contextmanager + + +@contextmanager +def state_call_context(func, **overrides): + ''' + Override specific variable within a state call context. + ''' + # recognize methods + if hasattr(func, "im_func"): + func = func.im_func + + # Get a reference to the function globals dictionary + func_globals = func.func_globals + # Save the current function globals dictionary state values for the + # overridden objects + injected_func_globals = [] + overridden_func_globals = {} + for override in overrides: + if override in func_globals: + overridden_func_globals[override] = func_globals[override] + else: + injected_func_globals.append(override) + + # Override the function globals with what's passed in the above overrides + func_globals.update(overrides) + + # The context is now ready to be used + yield + + # We're now done with the context + + # Restore the overwritten function globals + func_globals.update(overridden_func_globals) + + # Remove any entry injected in the function globals + for injected in injected_func_globals: + del func_globals[injected] From 2a1bb631a129087d32f12f3de04468c32c826898 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:26:04 +0000 Subject: [PATCH 07/30] Accepting `__env__` as a keyword argument is no longer required or aceptable --- salt/states/cmd.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/salt/states/cmd.py b/salt/states/cmd.py index 3a0120399f..820a52ab12 100644 --- a/salt/states/cmd.py +++ b/salt/states/cmd.py @@ -561,7 +561,6 @@ def script(name, stateful=False, umask=None, timeout=None, - __env__='base', **kwargs): ''' Download a script from a remote source and execute it. The name can be the @@ -621,11 +620,6 @@ def script(name, args String of command line args to pass to the script. Only used if no args are specified as part of the `name` argument. - - __env__ - The root directory of the environment for the referencing script. The - environments are defined in the master config file. - ''' ret = {'changes': {}, 'comment': '', @@ -639,7 +633,7 @@ def script(name, if isinstance(env, string_types): msg = ( 'Passing a salt environment should be done using \'__env__\' not ' - '\'env\'. This warning will go away in Salt {version} and this ' + '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' ) From a9a0dc319f771ba5161b2bf83a54303cc6ba8933 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:26:50 +0000 Subject: [PATCH 08/30] Accepting `__env__` as a keyword argument is no longer required or aceptable --- salt/states/pip_state.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/salt/states/pip_state.py b/salt/states/pip_state.py index 612a135676..2423ce819b 100644 --- a/salt/states/pip_state.py +++ b/salt/states/pip_state.py @@ -112,8 +112,7 @@ def installed(name, no_chown=False, cwd=None, activate=False, - pre_releases=False, - __env__='base'): + pre_releases=False): ''' Make sure the package is installed @@ -409,8 +408,7 @@ def removed(name, timeout=None, user=None, runas=None, - cwd=None, - __env__='base'): + cwd=None): ''' Make sure that a package is not installed. @@ -469,7 +467,7 @@ def removed(name, timeout=timeout, user=user, cwd=cwd, - __env__='base'): + __env__=__env__): ret['result'] = True ret['changes'][name] = 'Removed' ret['comment'] = 'Package was successfully removed.' From 79734ef8da7dcfcf096a895143658a731c746b1b Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:27:07 +0000 Subject: [PATCH 09/30] Accepting `__env__` as a keyword argument is no longer required or aceptable --- salt/states/ssh_auth.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/states/ssh_auth.py b/salt/states/ssh_auth.py index 4a1c4ee6b2..dc85f718eb 100644 --- a/salt/states/ssh_auth.py +++ b/salt/states/ssh_auth.py @@ -168,7 +168,7 @@ def present( options or [], source, config, - kwargs.get('__env__', 'base') + __env__ ) return ret @@ -177,7 +177,7 @@ def present( user, source, config, - kwargs.get('__env__', 'base')) + __env__) else: # check if this is of form {options} {enc} {key} {comment} sshre = re.compile(r'^(.*?)\s?((?:ssh\-|ecds)[\w-]+\s.+)$') From 294f32ceabe3a561dd8892f3d99f0822c2d9a44e Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:27:28 +0000 Subject: [PATCH 10/30] Accepting `__env__` as a keyword argument is no longer required or aceptable --- salt/states/virtualenv_mod.py | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/states/virtualenv_mod.py b/salt/states/virtualenv_mod.py index dc30d7744d..b64fe21c5b 100644 --- a/salt/states/virtualenv_mod.py +++ b/salt/states/virtualenv_mod.py @@ -34,7 +34,6 @@ def managed(name, extra_search_dir=None, never_download=None, prompt=None, - __env__='base', user=None, runas=None, no_chown=False, From 65d42890f221600f8988f01caeb962dc8d5f74e1 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:29:30 +0000 Subject: [PATCH 11/30] Deprecated `env` as a keyword argument since `__env__` is now available within the function's global scope. --- salt/states/cron.py | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/salt/states/cron.py b/salt/states/cron.py index b667f6f0b4..31dc4d7abd 100644 --- a/salt/states/cron.py +++ b/salt/states/cron.py @@ -63,7 +63,8 @@ keyword will not modify it. import os # Import salt libs -from salt.utils import mkstemp, fopen +import salt._compat +import salt.utils from salt.modules.cron import _needs_change @@ -311,8 +312,8 @@ def file(name, mode = __salt__['config.manage_mode'](600) owner, group, crontab_dir = _get_cron_info() - cron_path = mkstemp() - with fopen(cron_path, 'w+') as fp_: + cron_path = salt.utils.mkstemp() + with salt.utils.fopen(cron_path, 'w+') as fp_: fp_.write(__salt__['cron.raw_cron'](user)) ret = {'changes': {}, @@ -321,11 +322,19 @@ def file(name, 'result': True} # Avoid variable naming confusion in below module calls, since ID - # delclaration for this state will be a source URI. + # declaration for this state will be a source URI. source = name - if env is None: - env = kwargs.get('__env__', 'base') + if isinstance(env, salt._compat.string_types): + msg = ( + 'Passing a salt environment should be done using \'__env__\' not ' + '\'env\'. This warning will go away in Salt Helium and this ' + 'will be the default and expected behaviour. Please update your ' + 'state files.' + ) + salt.utils.warn_until('Helium', msg) + ret.setdefault('warnings', []).append(msg) + # No need to set __env__ = env since that's done in the state machinery if not replace and os.stat(cron_path).st_size > 0: ret['comment'] = 'User {0} already has a crontab. No changes ' \ @@ -344,7 +353,7 @@ def file(name, False, # makedirs = False context, defaults, - env, + __env__, **kwargs ) ret['result'], ret['comment'] = fcm From 80916c669842a3bd245f8204d2c91240e9ce48e2 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:30:32 +0000 Subject: [PATCH 12/30] Deprecated `env` as a keyword argument since `__env__` is now available within the function's global scope. --- salt/states/file.py | 84 ++++++++++++++++++++++++++++++++------------- 1 file changed, 60 insertions(+), 24 deletions(-) diff --git a/salt/states/file.py b/salt/states/file.py index 57e250da60..7ee850ab1e 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -640,7 +640,6 @@ def _get_template_texts(source_list=None, template='jinja', defaults=None, context=None, - env='base', **kwargs): ''' Iterate a list of sources and process them as templates. @@ -665,7 +664,7 @@ def _get_template_texts(source_list=None, if context: tmpctx.update(context) rndrd_templ_fn = __salt__['cp.get_template'](source, '', - template=template, env=env, + template=template, env=__env__, context=tmpctx, **kwargs) msg = 'cp.get_template returned {0} (Called with: {1})' log.debug(msg.format(rndrd_templ_fn, source)) @@ -1057,8 +1056,17 @@ def managed(name, if not os.path.isabs(name): return _error( ret, 'Specified file {0} is not an absolute path'.format(name)) - if env is None: - env = kwargs.get('__env__', 'base') + + if isinstance(env, salt._compat.string_types): + msg = ( + 'Passing a salt environment should be done using \'__env__\' not ' + '\'env\'. This warning will go away in Salt Helium and this ' + 'will be the default and expected behaviour. Please update your ' + 'state files.' + ) + salt.utils.warn_until('Helium', msg) + ret.setdefault('warnings', []).append(msg) + # No need to set __env__ = env since that's done in the state machinery if os.path.isdir(name): ret['comment'] = 'Specified target {0} is a directory'.format(name) @@ -1113,7 +1121,7 @@ def managed(name, makedirs, context, defaults, - env, + __env__, contents, **kwargs ) @@ -1123,7 +1131,7 @@ def managed(name, source, source_hash = __salt__['file.source_list']( source, source_hash, - env + __env__ ) # Gather the source file from the server @@ -1135,7 +1143,7 @@ def managed(name, user, group, mode, - env, + __env__, context, defaults, **kwargs @@ -1151,7 +1159,7 @@ def managed(name, user, group, mode, - env, + __env__, backup, template, show_diff, @@ -1513,15 +1521,24 @@ def recurse(name, if not os.path.isabs(name): return _error( ret, 'Specified file {0} is not an absolute path'.format(name)) - if env is None: - env = kwargs.get('__env__', 'base') + + if isinstance(env, salt._compat.string_types): + msg = ( + 'Passing a salt environment should be done using \'__env__\' not ' + '\'env\'. This warning will go away in Salt Helium and this ' + 'will be the default and expected behaviour. Please update your ' + 'state files.' + ) + salt.utils.warn_until('Helium', msg) + ret.setdefault('warnings', []).append(msg) + # No need to set __env__ = env since that's done in the state machinery # Verify the source exists. _src_proto, _src_path = source.split('://', 1) if not _src_path: pass - elif _src_path.strip('/') not in __salt__['cp.list_master_dirs'](env): + elif _src_path.strip('/') not in __salt__['cp.list_master_dirs'](__env__): ret['result'] = False ret['comment'] = ( 'The source: {0} does not exist on the master'.format(source) @@ -1591,7 +1608,7 @@ def recurse(name, context=context, replace=True, defaults=defaults, - env=env, + env=__env__, backup=backup, **pass_kwargs) merge_ret(path, _ret) @@ -1663,7 +1680,7 @@ def recurse(name, keep.add(os.path.join(name, srelpath)) return filenames # If source is a list, find which in the list actually exists - source, source_hash = __salt__['file.source_list'](source, '', env) + source, source_hash = __salt__['file.source_list'](source, '', __env__) keep = set() vdir = set() @@ -1672,11 +1689,11 @@ def recurse(name, #we're searching for things that start with this *directory*. # use '/' since #master only runs on POSIX srcpath = srcpath + '/' - fns_ = __salt__['cp.list_master'](env, srcpath) + fns_ = __salt__['cp.list_master'](__env__, srcpath) # If we are instructed to keep symlinks, then process them. if keep_symlinks: # Make this global so that emptydirs can use it if needed. - symlinks = __salt__['cp.list_master_symlinks'](env, srcpath) + symlinks = __salt__['cp.list_master_symlinks'](__env__, srcpath) fns_ = process_symlinks(fns_, symlinks) for fn_ in fns_: if not fn_.strip(): @@ -1718,7 +1735,7 @@ def recurse(name, manage_file(dest, src) if include_empty: - mdirs = __salt__['cp.list_master_dirs'](env, srcpath) + mdirs = __salt__['cp.list_master_dirs'](__env__, srcpath) for mdir in mdirs: if not _check_include_exclude(os.path.relpath(mdir, srcpath), include_pat, @@ -1729,7 +1746,8 @@ def recurse(name, if keep_symlinks: for link in symlinks: if mdir.startswith(link, 0): - log.debug('** skipping empty dir ** {0}, it intersects a symlink'.format(mdir)) + log.debug('** skipping empty dir ** {0}, it intersects' + ' a symlink'.format(mdir)) continue manage_directory(mdest) keep.add(mdest) @@ -2220,7 +2238,6 @@ def append(name, makedirs=False, source=None, source_hash=None, - __env__='base', template='jinja', sources=None, source_hashes=None, @@ -2302,8 +2319,7 @@ def append(name, tmpret = _get_template_texts(source_list=sl_, template=template, defaults=defaults, - context=context, - env=__env__) + context=context) if not tmpret['result']: return tmpret text = tmpret['data'] @@ -2415,10 +2431,19 @@ def patch(name, ret.update(result=True, comment='Patch is already applied') return ret + if isinstance(env, salt._compat.string_types): + msg = ( + 'Passing a salt environment should be done using \'__env__\' not ' + '\'env\'. This warning will go away in Salt Helium and this ' + 'will be the default and expected behaviour. Please update your ' + 'state files.' + ) + salt.utils.warn_until('Helium', msg) + ret.setdefault('warnings', []).append(msg) + # No need to set __env__ = env since that's done in the state machinery + # get cached file or copy it to cache - if env is None: - env = kwargs.get('__env__', 'base') - cached_source_path = __salt__['cp.cache_file'](source, env) + cached_source_path = __salt__['cp.cache_file'](source, __env__) log.debug( 'State patch.applied cached source {0} -> {1}'.format( source, cached_source_path @@ -2821,6 +2846,17 @@ def serialize(name, 'name': name, 'result': True} + if isinstance(env, salt._compat.string_types): + msg = ( + 'Passing a salt environment should be done using \'__env__\' not ' + '\'env\'. This warning will go away in Salt Helium and this ' + 'will be the default and expected behaviour. Please update your ' + 'state files.' + ) + salt.utils.warn_until('Helium', msg) + ret.setdefault('warnings', []).append(msg) + # No need to set __env__ = env since that's done in the state machinery + if not create: if not os.path.isfile(name): # Don't create a file that is not already present @@ -2854,7 +2890,7 @@ def serialize(name, user=user, group=group, mode=mode, - env=env, + env=__env__, backup=backup, template=None, show_diff=show_diff, From f9fca9b809d67a09a09e19a7bf42d63043b00779 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:31:00 +0000 Subject: [PATCH 13/30] Accepting `__env__` as a keyword argument is no longer required or aceptable --- salt/states/tomcat.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/salt/states/tomcat.py b/salt/states/tomcat.py index c928f232e7..4d9cc3abd4 100644 --- a/salt/states/tomcat.py +++ b/salt/states/tomcat.py @@ -51,8 +51,10 @@ def __virtual__(): # Functions -def war_deployed(name, war, url='http://localhost:8080/manager', - __env__='base', timeout=180): +def war_deployed(name, + war, + url='http://localhost:8080/manager', + timeout=180): ''' Enforce that the WAR will be deployed and started in the context path it will make use of WAR versions @@ -137,8 +139,12 @@ def war_deployed(name, war, url='http://localhost:8080/manager', return ret # Deploy - deploy_res = __salt__['tomcat.deploy_war'](war, name, 'yes', url, __env__, - timeout) + deploy_res = __salt__['tomcat.deploy_war'](war, + name, + 'yes', + url, + __env__, + timeout) # Return if deploy_res.startswith('OK'): From c170d1e57247c1894a8c8931eb7e73bd49b0c911 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:31:14 +0000 Subject: [PATCH 14/30] Updated test cases to include environment selection in states using `__env__`. --- tests/integration/modules/state.py | 1 + tests/integration/states/file.py | 58 ++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tests/integration/modules/state.py b/tests/integration/modules/state.py index fad4b89577..4bfc888b58 100644 --- a/tests/integration/modules/state.py +++ b/tests/integration/modules/state.py @@ -370,6 +370,7 @@ fi 'state.highstate', minion_tgt='sub_minion' ) self.assertSaltTrueReturn(ret) + self.assertTrue(os.path.isfile(tgt)) with salt.utils.fopen(tgt, 'r') as cheese: data = cheese.read() self.assertIn('Gromit', data) diff --git a/tests/integration/states/file.py b/tests/integration/states/file.py index f425b1207f..d44d2dd518 100644 --- a/tests/integration/states/file.py +++ b/tests/integration/states/file.py @@ -267,6 +267,22 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): if os.path.isdir(name): shutil.rmtree(name, ignore_errors=True) + def test_recurse_specific_env(self): + ''' + file.recurse passing __env__ + ''' + name = os.path.join(integration.TMP, 'recurse_dir_prod_env') + ret = self.run_state('file.recurse', + name=name, + source='salt://holy', + __env__='prod') + try: + self.assertSaltTrueReturn(ret) + self.assertTrue(os.path.isfile(os.path.join(name, '32', 'scene'))) + finally: + if os.path.isdir(name): + shutil.rmtree(name, ignore_errors=True) + def test_test_recurse(self): ''' file.recurse test interface @@ -279,6 +295,21 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): self.assertFalse(os.path.isfile(os.path.join(name, '36', 'scene'))) self.assertFalse(os.path.exists(name)) + def test_test_recurse_specific_env(self): + ''' + file.recurse test interface + ''' + name = os.path.join(integration.TMP, 'recurse_test_dir_prod_env') + ret = self.run_state('file.recurse', + test=True, + name=name, + source='salt://holy', + __env__='prod' + ) + self.assertSaltNoneReturn(ret) + self.assertFalse(os.path.isfile(os.path.join(name, '32', 'scene'))) + self.assertFalse(os.path.exists(name)) + def test_recurse_template(self): ''' file.recurse with jinja template enabled @@ -320,6 +351,33 @@ class FileTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): finally: shutil.rmtree(name, ignore_errors=True) + def test_recurse_clean_specific_env(self): + ''' + file.recurse with clean=True and __env__=prod + ''' + name = os.path.join(integration.TMP, 'recurse_clean_dir_prod_env') + if not os.path.isdir(name): + os.makedirs(name) + strayfile = os.path.join(name, 'strayfile') + salt.utils.fopen(strayfile, 'w').close() + + # Corner cases: replacing file with a directory and vice versa + salt.utils.fopen(os.path.join(name, '32'), 'w').close() + os.makedirs(os.path.join(name, 'scene34')) + ret = self.run_state('file.recurse', + name=name, + source='salt://holy', + clean=True, + __env__='prod') + try: + self.assertSaltTrueReturn(ret) + self.assertFalse(os.path.exists(strayfile)) + self.assertTrue(os.path.isfile(os.path.join(name, '32', 'scene'))) + self.assertTrue(os.path.isfile(os.path.join(name, 'scene34'))) + finally: + shutil.rmtree(name, ignore_errors=True) + + def test_replace(self): ''' file.replace From 56129e3610fb48739ce03b51710a3e58d1d68613 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:32:45 +0000 Subject: [PATCH 15/30] Include the `holy` directory for the `__env__` selection test cases. --- .../integration/files/file/prod/holy/32/scene | 58 +++++++++++++++++++ tests/integration/files/file/prod/holy/empty | 0 .../integration/files/file/prod/holy/scene34 | 52 +++++++++++++++++ 3 files changed, 110 insertions(+) create mode 100644 tests/integration/files/file/prod/holy/32/scene create mode 100644 tests/integration/files/file/prod/holy/empty create mode 100644 tests/integration/files/file/prod/holy/scene34 diff --git a/tests/integration/files/file/prod/holy/32/scene b/tests/integration/files/file/prod/holy/32/scene new file mode 100644 index 0000000000..c4823c63a4 --- /dev/null +++ b/tests/integration/files/file/prod/holy/32/scene @@ -0,0 +1,58 @@ +Scene 32 + + + ARTHUR: Knights! Forward! + [boom boom boom boom BOOM boom boom boom boom] + What manner of man are you that can summon up fire without flint + or tinder? + TIM: I... am an enchanter. + ARTHUR: By what name are you known? + TIM: There are some who call me... Tim? + ARTHUR: Greetings, Tim the Enchanter. + TIM: Greetings, King Arthur! + ARTHUR: You know my name? + TIM: I do. + [zoosh] + You seek the Holy Grail! + ARTHUR: That is our quest. You know much that is hidden, O Tim. + TIM: Quite. + [pweeng boom] + [clap clap clap] + ARTHUR: Yes, we're, we're looking for the Grail. Our quest is to find + the Holy Grail. + KNIGHTS: It is, yes, yup, yes, yeah. + ARTHUR: And so we're, we're, we're, we're looking for it. + KNIGHTS: Yes we are we are. + BEDEMIR: We have been for some time. + ROBIN: Ages. + ARTHUR: Uh, so, uh, anything you can do to, uh, to help, would be... + very... helpful... + GALAHAD: Look, can you tell us wh- + [boom] + ARTHUR: Fine, um, I don't want to waste anymore of your time, but, uh + I don't suppose you could, uh, tell us where we might find a, um, + find a, uh, a, um, a uh-- + TIM: A what...? + ARTHUR: A g--, a g-- + TIM: A Grail?! + ARTHUR: Yes, I think so. + KNIGHTS: Yes, that's it. Yes. + TIM: Yes! + KNIGHTS: Oh, thank you, splendid, fine. + [boom pweeng boom boom] + ARTHUR: Look, you're a busy man, uh-- + TIM: Yes, I can help you find the Holy Grail. + KNIGHTS: Oh, thank you. + TIM: To the north there lies a cave -- the cave of Kyre Banorg -- + wherein, carved in mystic runes upon the very living rock, the last + words of Ulfin Bedweer of Regett [boom] proclaim the last resting + place of the most Holy Grail. + ARTHUR: Where could we find this cave, O Tim? + TIM: Follow! But! follow only if ye be men of valor, for the entrance + to this cave is guarded by a creature so foul, so cruel that no man + yet has fought with it and lived! Bones of four fifty men lie strewn + about its lair. So, brave knights, if you do doubt your courage or + your strength, come no further, for death awaits you all with nasty + big pointy teeth. + ARTHUR: What an eccentric performance. + diff --git a/tests/integration/files/file/prod/holy/empty b/tests/integration/files/file/prod/holy/empty new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/integration/files/file/prod/holy/scene34 b/tests/integration/files/file/prod/holy/scene34 new file mode 100644 index 0000000000..1a5425055d --- /dev/null +++ b/tests/integration/files/file/prod/holy/scene34 @@ -0,0 +1,52 @@ +Scene 34 + + + KNIGHT: There! Look! + LAUNCELOT: What does it say? + GALAHAD: What language is that? + ARTHUR: Brother Maynard, you're our scholar! + MAYNARD: It's Aramaic! + GALAHAD: Of course! Joseph of Aramathea! + LAUNCELOT: Course! + KNIGHT: What does it say? + MAYNARD: It reads, 'Here may be found the last words of Joseph of + Aramathea. He who is valiant and pure of spirit may find the Holy Grail + in the Castle of uuggggggh'. + ARTHUR: What? + MAYNARD: '... the Castle of uuggggggh'. + BEDEMIR: What is that? + MAYNARD: He must have died while carving it. + LAUNCELOT: Oh, come on! + MAYNARD: Well, that's what it says. + ARTHUR: Look, if he was dying, he wouldn't bother to carve 'aaggggh'. + He'd just say it! + MAYNARD: Well, that's what's carved in the rock! + GALAHAD: Perhaps he was dictating. + ARTHUR: Oh, shut up. Well, does it say anything else? + MAYNARD: No. Just, 'uuggggggh'. + LAUNCELOT: Aauuggghhh. + KNIGHT: Aaauggh. + BEDEMIR: You don't suppose he meant the Camauuuugh? + KNIGHT: Where's that? + BEDEMIR: France, I think. + LAUNCELOT: Isn't there a Saint Aauuuves in Cornwall? + ARTHUR: No, that's Saint Ives. + LAUNCELOT: Oh, yes. Saint Iiiives. + SEVERAL: Iiiiives. + BEDEMIR: Oooohoohohooo! + LAUNCELOT: No, no, aauuuuugh, at the back of the throat. Aauuugh. + BEDEMIR: No, no, no, oooooooh, in surprise and alarm. + LAUNCELOT: Oh, you mean sort of a aaaagh! + BEDEMIR: Yes, but I-- Aaaaagh! + KNIGHT: Oooh! + KNIGHT: Oh, no! + [roar] + MAYNARD: It's the legendary Black Beast of aaauuugh! + ARTHUR: Run away! + ALL: Run away! Run away! + [roar] + NARRATOR: As the horrendous Black Beast lunged forward, escape + for Arthur and his knights seemed hopeless. When, suddenly, the + animator suffered a fatal heart attack. [ulk] The cartoon peril + was no more. The Quest for the Holy Grail could continue. + From 4c84b1da3e95a5debbe22ccac5d0313eb0b86e31 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 18:59:06 +0000 Subject: [PATCH 16/30] State unit tests need to have an hardcoded `__env__`. --- tests/unit/states/file_test.py | 1 + tests/unit/states/pip_test.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/unit/states/file_test.py b/tests/unit/states/file_test.py index 4090d9b34c..fb5f1fda96 100644 --- a/tests/unit/states/file_test.py +++ b/tests/unit/states/file_test.py @@ -14,6 +14,7 @@ import yaml # Import salt libs import salt.states.file as filestate +filestate.__env__ = 'base' filestate.__salt__ = {'file.manage_file': False} filestate.__opts__ = {'test': False} diff --git a/tests/unit/states/pip_test.py b/tests/unit/states/pip_test.py index c11b3ee059..e889122ed7 100644 --- a/tests/unit/states/pip_test.py +++ b/tests/unit/states/pip_test.py @@ -26,6 +26,7 @@ from salt.exceptions import CommandExecutionError # Import 3rd-party libs import pip +pip_state.__env__ = 'base' pip_state.__opts__ = {'test': False} pip_state.__salt__ = {'cmd.which_bin': lambda _: 'pip'} From fc229143d87faf9a555deabaa9bdf045d9e26f5b Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 19:48:57 +0000 Subject: [PATCH 17/30] Withing the module, `__env__` is known. --- salt/states/file.py | 1 - 1 file changed, 1 deletion(-) diff --git a/salt/states/file.py b/salt/states/file.py index 7ee850ab1e..e3a6391dc8 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -1608,7 +1608,6 @@ def recurse(name, context=context, replace=True, defaults=defaults, - env=__env__, backup=backup, **pass_kwargs) merge_ret(path, _ret) From c516595a27bc822130efd9be913911b6701d7fcd Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 22:39:39 +0000 Subject: [PATCH 18/30] The salt `pip` module no longer accepts `__env__` as `kwargs`. It simply knows that from it's global scope. --- salt/states/pip_state.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/salt/states/pip_state.py b/salt/states/pip_state.py index 2423ce819b..adcce47355 100644 --- a/salt/states/pip_state.py +++ b/salt/states/pip_state.py @@ -335,7 +335,6 @@ def installed(name, cwd=cwd, activate=activate, pre_releases=pre_releases, - __env__=__env__ ) if pip_install_call and (pip_install_call.get('retcode', 1) == 0): @@ -466,8 +465,7 @@ def removed(name, proxy=proxy, timeout=timeout, user=user, - cwd=cwd, - __env__=__env__): + cwd=cwd): ret['result'] = True ret['changes'][name] = 'Removed' ret['comment'] = 'Package was successfully removed.' From 9a22d3053eddf8b02602d35bcb0b6bb1271e71fc Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 23:03:31 +0000 Subject: [PATCH 19/30] The pip module no longer accepts `__env__` as a `kwarg`. --- salt/states/virtualenv_mod.py | 1 - tests/integration/runners/manage.py | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/states/virtualenv_mod.py b/salt/states/virtualenv_mod.py index b64fe21c5b..8c6637d6ea 100644 --- a/salt/states/virtualenv_mod.py +++ b/salt/states/virtualenv_mod.py @@ -180,7 +180,6 @@ def managed(name, index_url=index_url, extra_index_url=extra_index_url, no_chown=no_chown, - __env__=__env__, pre_releases=pre_releases ) ret['result'] &= _ret['retcode'] == 0 diff --git a/tests/integration/runners/manage.py b/tests/integration/runners/manage.py index 8e32ff020c..7243434549 100644 --- a/tests/integration/runners/manage.py +++ b/tests/integration/runners/manage.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- ''' Tests for the salt-run command ''' From 962f8d414982fa51ab18d25b1aa9ea3e615ff5da Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Sat, 2 Nov 2013 22:40:09 +0000 Subject: [PATCH 20/30] Support adding files to the testing prod state env. --- tests/integration/__init__.py | 21 ++++++++--- tests/integration/states/pip.py | 65 ++++++++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 11 deletions(-) diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py index a631cfc381..91a5e0499d 100644 --- a/tests/integration/__init__.py +++ b/tests/integration/__init__.py @@ -55,10 +55,11 @@ import yaml SYS_TMP_DIR = os.environ.get('TMPDIR', tempfile.gettempdir()) TMP = os.path.join(SYS_TMP_DIR, 'salt-tests-tmpdir') FILES = os.path.join(INTEGRATION_TEST_DIR, 'files') -PYEXEC = 'python{0}.{1}'.format(sys.version_info[0], sys.version_info[1]) +PYEXEC = 'python{0}.{1}'.format(*sys.version_info) MOCKBIN = os.path.join(INTEGRATION_TEST_DIR, 'mockbin') SCRIPT_DIR = os.path.join(CODE_DIR, 'scripts') TMP_STATE_TREE = os.path.join(SYS_TMP_DIR, 'salt-temp-state-tree') +TMP_PRODENV_STATE_TREE = os.path.join(SYS_TMP_DIR, 'salt-temp-prodenv-state-tree') TMP_CONF_DIR = os.path.join(TMP, 'config') log = logging.getLogger(__name__) @@ -168,7 +169,8 @@ class TestDaemon(object): ], # Alternate root to test __env__ choices 'prod': [ - os.path.join(FILES, 'file', 'prod') + os.path.join(FILES, 'file', 'prod'), + TMP_PRODENV_STATE_TREE ] } self.master_opts['ext_pillar'].append( @@ -179,7 +181,11 @@ class TestDaemon(object): ) )} ) - self.master_opts['extension_modules'] = os.path.join(INTEGRATION_TEST_DIR, 'files', 'extension_modules') + + self.master_opts['extension_modules'] = os.path.join( + INTEGRATION_TEST_DIR, 'files', 'extension_modules' + ) + # clean up the old files self._clean() @@ -210,7 +216,8 @@ class TestDaemon(object): self.sub_minion_opts['sock_dir'], self.minion_opts['sock_dir'], TMP_STATE_TREE, - TMP + TMP_PRODENV_STATE_TREE, + TMP, ], running_tests_user) @@ -414,8 +421,10 @@ class TestDaemon(object): shutil.rmtree(self.master_opts['root_dir']) if os.path.isdir(self.smaster_opts['root_dir']): shutil.rmtree(self.smaster_opts['root_dir']) - if os.path.isdir(TMP): - shutil.rmtree(TMP) + + for dirname in (TMP, TMP_STATE_TREE, TMP_PRODENV_STATE_TREE): + if os.path.isdir(dirname): + shutil.rmtree(dirname) def wait_for_jid(self, targets, jid, timeout=120): time.sleep(1) # Allow some time for minions to accept jobs diff --git a/tests/integration/states/pip.py b/tests/integration/states/pip.py index 07b2531483..de42f06164 100644 --- a/tests/integration/states/pip.py +++ b/tests/integration/states/pip.py @@ -26,6 +26,7 @@ ensure_in_syspath('../../') # Import salt libs import integration +import salt.utils class PipStateTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): @@ -192,7 +193,7 @@ class PipStateTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): if venv_create['retcode'] > 0: self.skipTest( 'Failed to create testcase virtual environment: {0}'.format( - ret + venv_create ) ) @@ -228,8 +229,8 @@ class PipStateTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): req_filename = os.path.join( integration.TMP_STATE_TREE, 'issue-6912-requirements.txt' ) - with open(req_filename, 'wb') as f: - f.write('pep8') + with salt.utils.fopen(req_filename, 'wb') as reqf: + reqf.write('pep8') try: ret = self.run_state( @@ -295,8 +296,8 @@ class PipStateTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): req_filename = os.path.join( integration.TMP_STATE_TREE, 'issue-6912-requirements.txt' ) - with open(req_filename, 'wb') as f: - f.write('pep8') + with salt.utils.fopen(req_filename, 'wb') as reqf: + reqf.write('pep8') try: ret = self.run_state( @@ -381,6 +382,60 @@ class PipStateTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn): if os.path.isdir(venv_dir): shutil.rmtree(venv_dir) + def test_pip_installed_specific_env(self): + # Create the testing virtualenv + venv_dir = os.path.join( + integration.TMP, 'pip-installed-specific-env' + ) + + # Let's write a requirements file + requirements_file = os.path.join( + integration.TMP_PRODENV_STATE_TREE, 'prod-env-requirements.txt' + ) + with salt.utils.fopen(requirements_file, 'wb') as reqf: + reqf.write('pep8\n') + + try: + ret = self.run_function('virtualenv.create', [venv_dir]) + + # The requirements file should not be found the base environment + ret = self.run_state( + 'pip.installed', name='', bin_env=venv_dir, + requirements='salt://prod-env-requirements.txt' + ) + self.assertSaltFalseReturn(ret) + self.assertInSaltComment( + "'salt://prod-env-requirements.txt' not found", ret + ) + + # The requirements file must be found in the prod environment + ret = self.run_state( + 'pip.installed', name='', bin_env=venv_dir, __env__='prod', + requirements='salt://prod-env-requirements.txt' + ) + self.assertSaltTrueReturn(ret) + self.assertInSaltComment( + 'Successfully processed requirements file ' + 'salt://prod-env-requirements.txt', ret + ) + + # We're using the base environment but we're passing the prod + # environment as an url arg to salt:// + ret = self.run_state( + 'pip.installed', name='', bin_env=venv_dir, + requirements='salt://prod-env-requirements.txt?env=prod' + ) + self.assertSaltTrueReturn(ret) + self.assertInSaltComment( + 'Successfully processed requirements file ' + 'salt://prod-env-requirements.txt', ret + ) + finally: + if os.path.isdir(venv_dir): + shutil.rmtree(venv_dir) + if os.path.isfile(requirements_file): + os.unlink(requirements_file) + if __name__ == '__main__': from integration import run_tests From 155422ff0f3465921212f13d0bc306a2c5057e6d Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 20:23:53 +0000 Subject: [PATCH 21/30] No need to set `__env__ = env` since that's done in function globals injection machinery. --- salt/states/cmd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/salt/states/cmd.py b/salt/states/cmd.py index 820a52ab12..de271b4481 100644 --- a/salt/states/cmd.py +++ b/salt/states/cmd.py @@ -639,8 +639,8 @@ def script(name, ) salt.utils.warn_until('Helium', msg) ret.setdefault('warnings', []).append(msg) - # Backwards compatibility - __env__ = env + # No need to set __env__ = env since that's done in function + # globals injection machinery if HAS_GRP: pgid = os.getegid() From edda49ae1fb94ed1bc7a3e4ac25a94e3baf89108 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 20:27:09 +0000 Subject: [PATCH 22/30] Deprecate passing `__env__` in states in favor of `saltenv` --- salt/states/cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/states/cmd.py b/salt/states/cmd.py index de271b4481..132dc86977 100644 --- a/salt/states/cmd.py +++ b/salt/states/cmd.py @@ -632,7 +632,7 @@ def script(name, if isinstance(env, string_types): msg = ( - 'Passing a salt environment should be done using \'__env__\' not ' + 'Passing a salt environment should be done using \'saltenv\' not ' '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' From 2eabe32d0c347e67bb128193fe8b11d7783d8248 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 20:27:53 +0000 Subject: [PATCH 23/30] Deprecate passing `__env__` in states in favor of `saltenv` --- salt/states/cron.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/salt/states/cron.py b/salt/states/cron.py index 31dc4d7abd..3e86963498 100644 --- a/salt/states/cron.py +++ b/salt/states/cron.py @@ -327,7 +327,7 @@ def file(name, if isinstance(env, salt._compat.string_types): msg = ( - 'Passing a salt environment should be done using \'__env__\' not ' + 'Passing a salt environment should be done using \'saltenv\' not ' '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' From 1b5e2ff63f8e7f2b44af820b4e2f2d8f9c28184d Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 20:28:28 +0000 Subject: [PATCH 24/30] Deprecate passing `__env__` in states in favor of `saltenv` --- salt/states/file.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/salt/states/file.py b/salt/states/file.py index e3a6391dc8..3f389d5983 100644 --- a/salt/states/file.py +++ b/salt/states/file.py @@ -1059,7 +1059,7 @@ def managed(name, if isinstance(env, salt._compat.string_types): msg = ( - 'Passing a salt environment should be done using \'__env__\' not ' + 'Passing a salt environment should be done using \'saltenv\' not ' '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' @@ -1524,7 +1524,7 @@ def recurse(name, if isinstance(env, salt._compat.string_types): msg = ( - 'Passing a salt environment should be done using \'__env__\' not ' + 'Passing a salt environment should be done using \'saltenv\' not ' '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' @@ -2432,7 +2432,7 @@ def patch(name, if isinstance(env, salt._compat.string_types): msg = ( - 'Passing a salt environment should be done using \'__env__\' not ' + 'Passing a salt environment should be done using \'saltenv\' not ' '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' @@ -2847,7 +2847,7 @@ def serialize(name, if isinstance(env, salt._compat.string_types): msg = ( - 'Passing a salt environment should be done using \'__env__\' not ' + 'Passing a salt environment should be done using \'saltenv\' not ' '\'env\'. This warning will go away in Salt Helium and this ' 'will be the default and expected behaviour. Please update your ' 'state files.' From fbfd926fdd0c7686b6be4da1dbfe4e9e18bbea60 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 20:30:11 +0000 Subject: [PATCH 25/30] `__env__` is now known in the module's global scope. --- salt/states/ssh_auth.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/salt/states/ssh_auth.py b/salt/states/ssh_auth.py index dc85f718eb..e6fce60fba 100644 --- a/salt/states/ssh_auth.py +++ b/salt/states/ssh_auth.py @@ -54,7 +54,7 @@ import re import sys -def _present_test(user, name, enc, comment, options, source, config, env): +def _present_test(user, name, enc, comment, options, source, config): ''' Run checks for "present" ''' @@ -64,7 +64,7 @@ def _present_test(user, name, enc, comment, options, source, config, env): user, source, config, - env) + __env__) if keys: comment = '' for key, status in keys.items(): @@ -168,7 +168,6 @@ def present( options or [], source, config, - __env__ ) return ret @@ -176,8 +175,7 @@ def present( data = __salt__['ssh.set_auth_key_from_file']( user, source, - config, - __env__) + config) else: # check if this is of form {options} {enc} {key} {comment} sshre = re.compile(r'^(.*?)\s?((?:ssh\-|ecds)[\w-]+\s.+)$') From 2869795802214d813ce53a6617519eead1a1ca99 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 20:56:10 +0000 Subject: [PATCH 26/30] Deprecate `__env__` in favor of `saltenv`. Formatting fixes. Additionally support passing the salt environment to the render template function. --- salt/modules/cmdmod.py | 91 ++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 29 deletions(-) diff --git a/salt/modules/cmdmod.py b/salt/modules/cmdmod.py index a698bd471b..4db128a993 100644 --- a/salt/modules/cmdmod.py +++ b/salt/modules/cmdmod.py @@ -114,7 +114,7 @@ def _chugid_and_umask(runas, umask): os.umask(umask) -def _render_cmd(cmd, cwd, template): +def _render_cmd(cmd, cwd, template, saltenv='base'): ''' If template is a valid template engine, process the cmd and cwd through that engine. @@ -134,7 +134,7 @@ def _render_cmd(cmd, cwd, template): kwargs['pillar'] = __pillar__ kwargs['grains'] = __grains__ kwargs['opts'] = __opts__ - kwargs['env'] = 'base' + kwargs['env'] = saltenv def _render(contents): # write out path to temp file @@ -178,7 +178,8 @@ def _run(cmd, umask=None, timeout=None, with_communicate=True, - reset_system_locale=True): + reset_system_locale=True, + saltenv='base'): ''' Do the DRY thing and only call subprocess.Popen() once ''' @@ -221,7 +222,7 @@ def _run(cmd, cmd = 'Powershell ' + cmd # munge the cmd and cwd through the template - (cmd, cwd) = _render_cmd(cmd, cwd, template) + (cmd, cwd) = _render_cmd(cmd, cwd, template, saltenv) ret = {} @@ -248,8 +249,9 @@ def _run(cmd, try: pwd.getpwnam(runas) except KeyError: - msg = 'User \'{0}\' is not available'.format(runas) - raise CommandExecutionError(msg) + raise CommandExecutionError( + 'User {0!r} is not available'.format(runas) + ) try: # Getting the environment for the runas user # There must be a better way to do this. @@ -276,8 +278,11 @@ def _run(cmd, env_runas.update(env) env = env_runas except ValueError: - msg = 'Environment could not be retrieved for User \'{0}\''.format(runas) - raise CommandExecutionError(msg) + raise CommandExecutionError( + 'Environment could not be retrieved for User {0!r}'.format( + runas + ) + ) if not salt.utils.is_true(quiet): # Put the most common case first @@ -388,7 +393,8 @@ def _run_quiet(cmd, template=None, umask=None, timeout=None, - reset_system_locale=True): + reset_system_locale=True, + saltenv='base'): ''' Helper for running commands quietly for minion startup ''' @@ -404,7 +410,8 @@ def _run_quiet(cmd, template=template, umask=umask, timeout=timeout, - reset_system_locale=reset_system_locale)['stdout'] + reset_system_locale=reset_system_locale, + saltenv=saltenv)['stdout'] def _run_all_quiet(cmd, @@ -417,7 +424,8 @@ def _run_all_quiet(cmd, template=None, umask=None, timeout=None, - reset_system_locale=True): + reset_system_locale=True, + saltenv='base'): ''' Helper for running commands quietly for minion startup. Returns a dict of return data @@ -433,7 +441,8 @@ def _run_all_quiet(cmd, template=template, umask=umask, timeout=timeout, - reset_system_locale=reset_system_locale) + reset_system_locale=reset_system_locale, + saltenv=saltenv) def run(cmd, @@ -450,6 +459,7 @@ def run(cmd, quiet=False, timeout=None, reset_system_locale=True, + saltenv='base', **kwargs): ''' Execute the passed command and return the output as a string @@ -499,7 +509,8 @@ def run(cmd, umask=umask, quiet=quiet, timeout=timeout, - reset_system_locale=reset_system_locale)['stdout'] + reset_system_locale=reset_system_locale, + saltenv=saltenv)['stdout'] if not quiet: log.debug('output: {0}'.format(out)) return out @@ -519,6 +530,7 @@ def run_stdout(cmd, quiet=False, timeout=None, reset_system_locale=True, + saltenv='base', **kwargs): ''' Execute a command, and only return the standard out @@ -561,7 +573,8 @@ def run_stdout(cmd, umask=umask, quiet=quiet, timeout=timeout, - reset_system_locale=reset_system_locale)["stdout"] + reset_system_locale=reset_system_locale, + saltenv=saltenv)['stdout'] if not quiet: log.debug('stdout: {0}'.format(stdout)) return stdout @@ -581,6 +594,7 @@ def run_stderr(cmd, quiet=False, timeout=None, reset_system_locale=True, + saltenv='base', **kwargs): ''' Execute a command and only return the standard error @@ -623,7 +637,8 @@ def run_stderr(cmd, umask=umask, quiet=quiet, timeout=timeout, - reset_system_locale=reset_system_locale)["stderr"] + reset_system_locale=reset_system_locale, + saltenv=saltenv)['stderr'] if not quiet: log.debug('stderr: {0}'.format(stderr)) return stderr @@ -643,6 +658,7 @@ def run_all(cmd, quiet=False, timeout=None, reset_system_locale=True, + saltenv='base', **kwargs): ''' Execute the passed command and return a dict of return data @@ -685,13 +701,15 @@ def run_all(cmd, umask=umask, quiet=quiet, timeout=timeout, - reset_system_locale=reset_system_locale) + reset_system_locale=reset_system_locale, + saltenv=saltenv) if not quiet: if ret['retcode'] != 0: rcode = ret['retcode'] - msg = 'Command \'{0}\' failed with return code: {1}' - log.error(msg.format(cmd, rcode)) + log.error( + 'Command {0!r} failed with return code: {1}'.format(cmd, rcode) + ) # Don't log a blank line if there is no stderr or stdout if ret['stdout']: log.error('stdout: {0}'.format(ret['stdout'])) @@ -719,6 +737,7 @@ def retcode(cmd, quiet=False, timeout=None, reset_system_locale=True, + saltenv='base', **kwargs): ''' Execute a shell command and return the command's return code. @@ -761,7 +780,8 @@ def retcode(cmd, quiet=quiet, timeout=timeout, with_communicate=False, - reset_system_locale=reset_system_locale)['retcode'] + reset_system_locale=reset_system_locale, + saltenv=saltenv)['retcode'] def script(source, @@ -776,7 +796,8 @@ def script(source, umask=None, timeout=None, reset_system_locale=True, - __env__='base', + __env__=None, + saltenv='base', **kwargs): ''' Download a script from a remote location and execute the script locally. @@ -812,19 +833,19 @@ def script(source, log.error('cmd.script: Unable to clean tempfile {0!r}: {1}' .format(path, exc)) - if isinstance(env, string_types): + if isinstance(__env__, string_types): salt.utils.warn_until( 'Helium', - 'Passing a salt environment should be done using \'__env__\' not ' - '\'env\'. This functionality will be removed in Salt {version}.' + 'Passing a salt environment should be done using \'saltenv\' not ' + '\'__env__\'. This functionality will be removed in Salt Helium.' ) # Backwards compatibility - __env__ = env + saltenv = __env__ if not salt.utils.is_windows(): path = salt.utils.mkstemp(dir=cwd) else: - path = __salt__['cp.cache_file'](source, __env__) + path = __salt__['cp.cache_file'](source, saltenv) if not path: _cleanup_tempfile(path) return {'pid': 0, @@ -837,7 +858,7 @@ def script(source, fn_ = __salt__['cp.get_template'](source, path, template, - __env__, + saltenv, **kwargs) if not fn_: _cleanup_tempfile(path) @@ -848,7 +869,7 @@ def script(source, 'cache_error': True} else: if not salt.utils.is_windows(): - fn_ = __salt__['cp.cache_file'](source, __env__) + fn_ = __salt__['cp.cache_file'](source, saltenv) if not fn_: _cleanup_tempfile(path) return {'pid': 0, @@ -869,7 +890,8 @@ def script(source, python_shell=python_shell, umask=umask, timeout=timeout, - reset_system_locale=reset_system_locale) + reset_system_locale=reset_system_locale, + saltenv=saltenv) _cleanup_tempfile(path) return ret @@ -885,7 +907,8 @@ def script_retcode(source, umask=None, timeout=None, reset_system_locale=True, - __env__='base', + __env__=None, + saltenv='base' **kwargs): ''' Download a script from a remote location and execute the script locally. @@ -913,6 +936,15 @@ def script_retcode(source, salt '*' cmd.script_retcode salt://scripts/runme.sh stdin='one\\ntwo\\nthree\\nfour\\nfive\\n' ''' + if isinstance(__env__, string_types): + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' not ' + '\'env\'. This functionality will be removed in Salt Helium.' + ) + # Backwards compatibility + saltenv = __env__ + return script(source=source, cwd=cwd, stdin=stdin, @@ -924,6 +956,7 @@ def script_retcode(source, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, + saltenv=saltenv, **kwargs)['retcode'] From 7601e468258b354cfd67843247153637a403cc83 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 21:54:05 +0000 Subject: [PATCH 27/30] Deprecate `__env__` in favor of `saltenv` --- salt/modules/debconfmod.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/salt/modules/debconfmod.py b/salt/modules/debconfmod.py index c05bc4a9cc..feb90ec325 100644 --- a/salt/modules/debconfmod.py +++ b/salt/modules/debconfmod.py @@ -134,7 +134,7 @@ def set_(package, question, type, value, *extra): return True -def set_file(path, **kwargs): +def set_file(path, saltenv='base', **kwargs): ''' Set answers to debconf questions from a file. @@ -144,7 +144,15 @@ def set_file(path, **kwargs): salt '*' debconf.set_file salt://pathto/pkg.selections ''' - path = __salt__['cp.cache_file'](path, kwargs.get('__env__', 'base')) + if '__env__' in kwargs: + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' not ' + '\'__env__\'. This functionality will be removed in Salt Helium.' + ) + # Backwards compatibility + saltenv = kwargs['__env__'] + path = __salt__['cp.cache_file'](path, saltenv) if path: _set_file(path) return True From 69c3bf328b6a83ee5eb2e6b2a23e4d36e0b91c42 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 21:54:53 +0000 Subject: [PATCH 28/30] Deprecate `__env__` and `env` in favor of `saltenv` --- salt/modules/dockerio.py | 52 +++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/salt/modules/dockerio.py b/salt/modules/dockerio.py index ef2be283ac..0a2232efc7 100644 --- a/salt/modules/dockerio.py +++ b/salt/modules/dockerio.py @@ -1966,34 +1966,37 @@ def _script(status, stdin=None, runas=None, shell=cmdmod.DEFAULT_SHELL, - env=(), + env=None, template='jinja', umask=None, timeout=None, reset_system_locale=True, - __env__='base', run_func_=None, no_clean=False, + saltenv='base', **kwargs): try: if not run_func_: run_func_ = run_all rpath = get_container_root(container) tpath = os.path.join(rpath, 'tmp') + if isinstance(env, string_types): salt.utils.warn_until( 'Helium', - 'Passing a salt environment should be done using \'__env__\' ' - 'not \'env\'.' + 'Passing a salt environment should be done using \'saltenv\' ' + 'not \'env\'. This functionality will be removed in Salt ' + 'Helium.' ) # Backwards compatibility - __env__ = env + saltenv = env + path = salt.utils.mkstemp(dir=tpath) if template: __salt__['cp.get_template']( - source, path, template, __env__, **kwargs) + source, path, template, saltenv, **kwargs) else: - fn_ = __salt__['cp.cache_file'](source, __env__) + fn_ = __salt__['cp.cache_file'](source, saltenv) if not fn_: return {'pid': 0, 'retcode': 1, @@ -2028,13 +2031,13 @@ def script(container, stdin=None, runas=None, shell=cmdmod.DEFAULT_SHELL, - env=(), + env=None, template='jinja', umask=None, timeout=None, reset_system_locale=True, - __env__='base', no_clean=False, + saltenv='base' *nargs, **kwargs): ''' @@ -2057,6 +2060,17 @@ def script(container, salt '*' docker.script salt://docker_script.py ''' status = base_status.copy() + + if isinstance(env, string_types): + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' ' + 'not \'env\'. This functionality will be removed in Salt ' + 'Helium.' + ) + # Backwards compatibility + saltenv = env + return _script(status, container, source, @@ -2065,13 +2079,12 @@ def script(container, stdin=stdin, runas=runas, shell=shell, - env=env, template=template, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, - __env__=__env__, no_clean=no_clean, + saltenv=saltenv, **kwargs) @@ -2081,13 +2094,13 @@ def script_retcode(container, stdin=None, runas=None, shell=cmdmod.DEFAULT_SHELL, - env=(), + env=None, template='jinja', umask=None, timeout=None, reset_system_locale=True, - __env__='base', no_clean=False, + saltenv='base', *args, **kwargs): ''' @@ -2109,17 +2122,28 @@ def script_retcode(container, salt '*' docker.script_retcode salt://docker_script.py ''' + + if isinstance(env, string_types): + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' ' + 'not \'env\'. This functionality will be removed in Salt ' + 'Helium.' + ) + # Backwards compatibility + saltenv = env + return _script(container, source=source, cwd=cwd, stdin=stdin, runas=runas, shell=shell, - env=env, template=template, umask=umask, timeout=timeout, reset_system_locale=reset_system_locale, run_func_=retcode, no_clean=no_clean, + saltenv=saltenv, **kwargs) From 9c493ba0e6bdb542fbdb2b9e1f6fc130a34672e7 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 22:00:51 +0000 Subject: [PATCH 29/30] Deprecate `__env__` and `env` in favor of `saltenv` --- salt/modules/pip.py | 46 +++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/salt/modules/pip.py b/salt/modules/pip.py index 3f8cbdf090..c9fe165d02 100644 --- a/salt/modules/pip.py +++ b/salt/modules/pip.py @@ -52,21 +52,21 @@ def _get_pip_bin(bin_env): return bin_env -def _get_cached_requirements(requirements, __env__): +def _get_cached_requirements(requirements, saltenv): '''Get the location of a cached requirements file; caching if necessary.''' cached_requirements = __salt__['cp.is_cached']( - requirements, __env__ + requirements, saltenv ) if not cached_requirements: # It's not cached, let's cache it. cached_requirements = __salt__['cp.cache_file']( - requirements, __env__ + requirements, saltenv ) # Check if the master version has changed. - if __salt__['cp.hash_file'](requirements, __env__) != \ - __salt__['cp.hash_file'](cached_requirements, __env__): + if __salt__['cp.hash_file'](requirements, saltenv) != \ + __salt__['cp.hash_file'](cached_requirements, saltenv): cached_requirements = __salt__['cp.cache_file']( - requirements, __env__ + requirements, saltenv ) return cached_requirements @@ -120,7 +120,8 @@ def install(pkgs=None, cwd=None, activate=False, pre_releases=False, - __env__='base'): + __env__=None, + saltenv='base'): ''' Install packages with pip @@ -245,6 +246,16 @@ def install(pkgs=None, if env and not bin_env: bin_env = env + if isinstance(__env__, string_types): + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' ' + 'not \'__env__\'. This functionality will be removed in Salt ' + 'Helium.' + ) + # Backwards compatibility + saltenv = __env__ + if runas is not None: # The user is using a deprecated argument, warn! salt.utils.warn_until( @@ -279,7 +290,7 @@ def install(pkgs=None, treq = None if requirement.startswith('salt://'): cached_requirements = _get_cached_requirements( - requirement, __env__ + requirement, saltenv ) if not cached_requirements: return { @@ -481,7 +492,7 @@ def install(pkgs=None, cmd.append('--editable={0}'.format(entry)) try: - cmd_kwargs = dict(runas=user, cwd=cwd) + cmd_kwargs = dict(runas=user, cwd=cwd, saltenv=saltenv) if bin_env and os.path.isdir(bin_env): cmd_kwargs['env'] = {'VIRTUAL_ENV': bin_env} return __salt__['cmd.run_all'](' '.join(cmd), **cmd_kwargs) @@ -503,7 +514,8 @@ def uninstall(pkgs=None, runas=None, no_chown=False, cwd=None, - __env__='base'): + __env__=None, + saltenv='base'): ''' Uninstall packages with pip @@ -556,6 +568,16 @@ def uninstall(pkgs=None, ''' cmd = [_get_pip_bin(bin_env), 'uninstall', '-y'] + if isinstance(__env__, string_types): + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' ' + 'not \'__env__\'. This functionality will be removed in Salt ' + 'Helium.' + ) + # Backwards compatibility + saltenv = __env__ + if runas is not None: # The user is using a deprecated argument, warn! salt.utils.warn_until( @@ -584,7 +606,7 @@ def uninstall(pkgs=None, treq = None if requirement.startswith('salt://'): cached_requirements = _get_cached_requirements( - requirement, __env__ + requirement, saltenv ) if not cached_requirements: return { @@ -636,7 +658,7 @@ def uninstall(pkgs=None, pkgs = [p.strip() for p in pkgs.split(',')] cmd.extend(pkgs) - cmd_kwargs = dict(runas=user, cwd=cwd) + cmd_kwargs = dict(runas=user, cwd=cwd, saltenv=saltenv) if bin_env and os.path.isdir(bin_env): cmd_kwargs['env'] = {'VIRTUAL_ENV': bin_env} From fce52f87eecfa9602badcad7f3cba702bcc87bb4 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Wed, 6 Nov 2013 22:04:01 +0000 Subject: [PATCH 30/30] Deprecate `__env__` in favor of `saltenv` --- salt/modules/pkg_resource.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/salt/modules/pkg_resource.py b/salt/modules/pkg_resource.py index 72bc75444d..45c2a36034 100644 --- a/salt/modules/pkg_resource.py +++ b/salt/modules/pkg_resource.py @@ -191,7 +191,11 @@ def _verify_binary_pkg(srcinfo): return problems -def parse_targets(name=None, pkgs=None, sources=None, **kwargs): +def parse_targets(name=None, + pkgs=None, + sources=None, + saltenv='base', + **kwargs): ''' Parses the input to pkg.install and returns back the package(s) to be installed. Returns a list of packages, as well as a string noting whether @@ -203,6 +207,16 @@ def parse_targets(name=None, pkgs=None, sources=None, **kwargs): salt '*' pkg_resource.parse_targets ''' + if '__env__' in kwargs: + salt.utils.warn_until( + 'Helium', + 'Passing a salt environment should be done using \'saltenv\' ' + 'not \'__env__\'. This functionality will be removed in Salt ' + 'Helium.' + ) + # Backwards compatibility + saltenv = kwargs['__env__'] + if __grains__['os'] == 'MacOS' and sources: log.warning('Parameter "sources" ignored on MacOS hosts.') @@ -228,9 +242,7 @@ def parse_targets(name=None, pkgs=None, sources=None, **kwargs): # Cache package from remote source (salt master, HTTP, FTP) srcinfo.append((pkg_name, pkg_src, - __salt__['cp.cache_file'](pkg_src, - kwargs.get('__env__', - 'base')), + __salt__['cp.cache_file'](pkg_src, saltenv), 'remote')) else: # Package file local to the minion