Merge remote-tracking branch 'upstream/develop' into feature_sqlite3_returner

This commit is contained in:
Mickey Malone 2013-09-11 22:07:01 -05:00
commit 5601cbb3af
29 changed files with 340 additions and 61 deletions

View File

@ -77,7 +77,7 @@ of libvirt certificates. These certificates allow for virtual machine
migration. Salt comes with a system used to auto deploy these certificates. migration. Salt comes with a system used to auto deploy these certificates.
Salt manages the signing authority key and generates keys for libvirt clients Salt manages the signing authority key and generates keys for libvirt clients
on the master, signs them with the certificate authority and uses pillar to on the master, signs them with the certificate authority and uses pillar to
distrbute them. This is managed via the ``libvirt`` state. Simply execute this distribute them. This is managed via the ``libvirt`` state. Simply execute this
formula on the minion to ensure that the certificate is in place and up to formula on the minion to ensure that the certificate is in place and up to
date: date:

View File

@ -616,11 +616,11 @@ def prep_trans_tar(opts, chunks, file_refs):
break break
files = file_client.cache_dir(name, env, True) files = file_client.cache_dir(name, env, True)
if files: if files:
for file in files: for filename in files:
tgt = os.path.join( tgt = os.path.join(
env_root, env_root,
short, short,
file[file.find(short) + len(short):], filename[filename.find(short) + len(short):],
) )
tgt_dir = os.path.dirname(tgt) tgt_dir = os.path.dirname(tgt)
if not os.path.isdir(tgt_dir): if not os.path.isdir(tgt_dir):

View File

@ -128,11 +128,11 @@ def prep_trans_tar(opts, chunks, file_refs):
break break
files = file_client.cache_dir(name, env, True) files = file_client.cache_dir(name, env, True)
if files: if files:
for file in files: for filename in files:
tgt = os.path.join( tgt = os.path.join(
env_root, env_root,
short, short,
file[file.find(short) + len(short):], filename[filename.find(short) + len(short):],
) )
tgt_dir = os.path.dirname(tgt) tgt_dir = os.path.dirname(tgt)
if not os.path.isdir(tgt_dir): if not os.path.isdir(tgt_dir):

View File

@ -190,7 +190,7 @@ def fileserver(opts, backends):
def roster(opts, whitelist=None): def roster(opts, whitelist=None):
''' '''
Returns the file server modules Returns the roster modules
''' '''
load = _create_loader(opts, 'roster', 'roster') load = _create_loader(opts, 'roster', 'roster')
ret = load.gen_functions(whitelist=whitelist) ret = load.gen_functions(whitelist=whitelist)

View File

@ -1896,7 +1896,7 @@ class ClearFuncs(object):
self.event.fire_event(data, tagify([jid, 'new'], 'wheel')) self.event.fire_event(data, tagify([jid, 'new'], 'wheel'))
ret = self.wheel_.call_func(fun, **clear_load.get('kwarg', {})) ret = self.wheel_.call_func(fun, **clear_load.get('kwarg', {}))
data['ret'] = ret data['ret'] = ret
self.event.fire_event(data, tagify([jid, 'ret'], 'wheel')) self.event.fire_event(data, tagify([jid, 'ret'], 'wheel'))
return data return data
except Exception as exc: except Exception as exc:
log.error(exc) log.error(exc)
@ -1915,7 +1915,7 @@ class ClearFuncs(object):
'user {0}.').format(clear_load.get('username', 'UNKNOWN')) 'user {0}.').format(clear_load.get('username', 'UNKNOWN'))
log.warning(msg) log.warning(msg)
return '' return ''
try: try:
name = self.loadauth.load_name(clear_load) name = self.loadauth.load_name(clear_load)
if not ((name in self.opts['external_auth'][clear_load['eauth']]) | ('*' in self.opts['external_auth'][clear_load['eauth']])): if not ((name in self.opts['external_auth'][clear_load['eauth']]) | ('*' in self.opts['external_auth'][clear_load['eauth']])):

View File

@ -23,6 +23,11 @@ __outputter__ = {
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Don't shadow built-in's.
__func_alias__ = {
'set_': 'set'
}
def __virtual__(): def __virtual__():
''' '''
@ -151,7 +156,7 @@ def auto(name):
return out['stdout'] return out['stdout']
def set(name, path): def set_(name, path):
''' '''
Manually set the alternative <path> for <name>. Manually set the alternative <path> for <name>.

View File

@ -6,15 +6,15 @@ access to the master root execution access to all salt minions
''' '''
# Import python libs # Import python libs
import functools
import json
import logging import logging
import os import os
import shutil import shutil
import subprocess import subprocess
import functools
import sys import sys
import json
import yaml
import traceback import traceback
import yaml
# Import salt libs # Import salt libs
import salt.utils import salt.utils
@ -174,8 +174,9 @@ def _run(cmd,
''' '''
Do the DRY thing and only call subprocess.Popen() once Do the DRY thing and only call subprocess.Popen() once
''' '''
# Set the default working directory to the home directory # Set the default working directory to the home directory of the user
# of the user salt-minion is running as. Default: /root # salt-minion is running as. Defaults to home directory of user under which
# the minion is running.
if not cwd: if not cwd:
cwd = os.path.expanduser('~{0}'.format('' if not runas else runas)) cwd = os.path.expanduser('~{0}'.format('' if not runas else runas))
@ -187,6 +188,10 @@ def _run(cmd,
cwd = '/' cwd = '/'
if salt.utils.is_windows(): if salt.utils.is_windows():
cwd = os.tempnam()[:3] cwd = os.tempnam()[:3]
else:
# Handle edge cases where numeric/other input is entered, and would be
# yaml-ified into non-string types
cwd = str(cwd)
if not salt.utils.is_windows(): if not salt.utils.is_windows():
if not os.path.isfile(shell) or not os.access(shell, os.X_OK): if not os.path.isfile(shell) or not os.access(shell, os.X_OK):
@ -296,7 +301,7 @@ def _run(cmd,
'stdin': str(stdin) if stdin is not None else stdin, 'stdin': str(stdin) if stdin is not None else stdin,
'stdout': stdout, 'stdout': stdout,
'stderr': stderr, 'stderr': stderr,
'with_communicate' : with_communicate} 'with_communicate': with_communicate}
if umask: if umask:
try: try:
@ -321,8 +326,18 @@ def _run(cmd,
kwargs['executable'] = shell kwargs['executable'] = shell
kwargs['close_fds'] = True kwargs['close_fds'] = True
if not os.path.isabs(cwd) or not os.path.isdir(cwd):
raise CommandExecutionError(
'Specified cwd {0!r} either not absolute or does not exist'
.format(cwd)
)
# This is where the magic happens # This is where the magic happens
proc = salt.utils.timed_subprocess.TimedProc(cmd, **kwargs) try:
proc = salt.utils.timed_subprocess.TimedProc(cmd, **kwargs)
except (OSError, IOError) as exc:
raise CommandExecutionError('Unable to run command: {0}'.format(exc))
try: try:
proc.wait(timeout) proc.wait(timeout)
except salt.exceptions.TimedProcTimeoutError, e: except salt.exceptions.TimedProcTimeoutError, e:

View File

@ -1,5 +1,5 @@
''' '''
Manage information about regular files, directories, Manage information about regular files, directories,
and special files on the minion, set/read user, and special files on the minion, set/read user,
group, mode, and data group, mode, and data
''' '''

View File

@ -15,6 +15,11 @@ import salt.utils
# Set up logging # Set up logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Don't shadow built-in's.
__func_alias__ = {
'list_': 'list'
}
def __virtual__(): def __virtual__():
if not salt.utils.which('lxc'): if not salt.utils.which('lxc'):
@ -217,7 +222,7 @@ def create(name, config=None, profile=None, options=None, **kwargs):
return {'created': False, 'error': 'container could not be created'} return {'created': False, 'error': 'container could not be created'}
def list(): def list_():
''' '''
List defined containers (running, stopped, and frozen). List defined containers (running, stopped, and frozen).

View File

@ -203,7 +203,7 @@ def list_running_members(lbn, profile='default'):
salt '*' modjk.list_running_members loadbalancer1 other-profile salt '*' modjk.list_running_members loadbalancer1 other-profile
''' '''
config = get_running() config = get_running(profile)
try: try:
return config['worker.{0}.balance_workers'.format(lbn)].split(',') return config['worker.{0}.balance_workers'.format(lbn)].split(',')
except KeyError: except KeyError:

View File

@ -727,7 +727,9 @@ def list_(prefix=None,
''' '''
packages = {} packages = {}
cmd = [_get_pip_bin(bin_env), 'freeze'] pip_bin = _get_pip_bin(bin_env)
pip_version_cmd = [pip_bin, '--version']
cmd = [pip_bin, 'freeze']
if runas is not None: if runas is not None:
# The user is using a deprecated argument, warn! # The user is using a deprecated argument, warn!
@ -751,6 +753,14 @@ def list_(prefix=None,
cmd_kwargs = dict(runas=user, cwd=cwd) cmd_kwargs = dict(runas=user, cwd=cwd)
if bin_env and os.path.isdir(bin_env): if bin_env and os.path.isdir(bin_env):
cmd_kwargs['env'] = {'VIRTUAL_ENV': bin_env} cmd_kwargs['env'] = {'VIRTUAL_ENV': bin_env}
if not prefix or prefix in ('p', 'pi', 'pip'):
pip_version_result = __salt__['cmd.run_all'](' '.join(pip_version_cmd),
**cmd_kwargs)
if pip_version_result['retcode'] > 0:
raise CommandExecutionError(pip_version_result['stderr'])
packages['pip'] = pip_version_result['stdout'].split()[1]
result = __salt__['cmd.run_all'](' '.join(cmd), **cmd_kwargs) result = __salt__['cmd.run_all'](' '.join(cmd), **cmd_kwargs)
if result['retcode'] > 0: if result['retcode'] > 0:
raise CommandExecutionError(result['stderr']) raise CommandExecutionError(result['stderr'])

View File

@ -378,7 +378,7 @@ def list_queues_vhost(vhost, *kwargs):
def list_policies(runas=None): def list_policies(runas=None):
''' '''
Return a dictionary of policies nested by vhost and name Return a dictionary of policies nested by vhost and name
based on the data returned from rabbitmqctl list_policies. based on the data returned from rabbitmqctl list_policies.
Reference: http://www.rabbitmq.com/ha.html Reference: http://www.rabbitmq.com/ha.html

View File

@ -19,6 +19,11 @@ import salt.config
# Set up logging # Set up logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
# Don't shadow built-in's.
__func_alias__ = {
'apply_': 'apply'
}
def _mount(path, ftype): def _mount(path, ftype):
mpt = None mpt = None
@ -44,7 +49,7 @@ def _umount(mpt, ftype):
__salt__['img.umount_image'](mpt) __salt__['img.umount_image'](mpt)
def apply(path, id_=None, config=None, approve_key=True, install=True): def apply_(path, id_=None, config=None, approve_key=True, install=True):
''' '''
Seed a location (disk image, directory, or block device) with the Seed a location (disk image, directory, or block device) with the
minion config, approve the minion's key, and/or install salt-minion. minion config, approve the minion's key, and/or install salt-minion.

View File

@ -166,7 +166,7 @@ def _wget(cmd, opts=None, url='http://localhost:8080/manager', timeout=180):
ret['msg'] = urllib2.urlopen(url6, timeout=timeout).read().splitlines() ret['msg'] = urllib2.urlopen(url6, timeout=timeout).read().splitlines()
except Exception: except Exception:
ret['msg'] = 'Failed to create HTTP request' ret['msg'] = 'Failed to create HTTP request'
if not ret['msg'][0].startswith('OK'): if not ret['msg'][0].startswith('OK'):
ret['res'] = False ret['res'] = False

View File

@ -293,7 +293,7 @@ def restart(name, **kwargs):
return not __salt__['cmd.retcode'](cmd) return not __salt__['cmd.retcode'](cmd)
def full_restart(name, **kwargs): def full_restart(name):
''' '''
Do a full restart (stop/start) of the named service Do a full restart (stop/start) of the named service

View File

@ -12,7 +12,6 @@ ext_pillar:
from copy import deepcopy from copy import deepcopy
import logging import logging
import os import os
import time
# Import third party libs # Import third party libs
HAS_GIT = False HAS_GIT = False
@ -23,7 +22,6 @@ except ImportError:
pass pass
# Import salt libs # Import salt libs
import salt.utils
from salt.pillar import Pillar from salt.pillar import Pillar
# Set up logging # Set up logging

View File

@ -3,6 +3,51 @@ Pure python state renderer
The sls file should contain a function called ``run`` which returns high state The sls file should contain a function called ``run`` which returns high state
data data
In this module, a few objects are defined for you, including the usual
(with``__`` added) ``__salt__`` dictionary, ``__grains__``,
``__pillar__``, ``__opts__``, ``__env__``, and ``__sls__``.
.. code-block:: python
:linenos:
#!py
def run():
config = {}
if __grains__['os'] == 'Ubuntu':
user = 'ubuntu'
group = 'ubuntu'
home = '/home/{0}'.format(user)
else:
user = 'root'
group = 'root'
home = '/root/'
config['s3cmd'] = {
'pkg': [
'installed',
{'name': 's3cmd'},
],
}
config[home + '/.s3cfg'} = {
'file.managed': [{
'source': 'salt://s3cfg/templates/s3cfg',
'template': 'jinja',
'user': user,
'group': group,
'mode': 600,
'context': {
'aws_key': __pillar__['AWS_ACCESS_KEY_ID'],
'aws_secret_key': __pillar__['AWS_SECRET_ACCESS_KEY'],
},
}],
}
return config
''' '''
# Import python libs # Import python libs
@ -26,12 +71,12 @@ def render(template, env='', sls='', tmplpath=None, **kws):
tmp_data = salt.utils.templates.py( tmp_data = salt.utils.templates.py(
template, template,
True, True,
salt=__salt__, __salt__=__salt__,
grains=__grains__, __grains__=__grains__,
opts=__opts__, __opts__=__opts__,
pillar=__pillar__, __pillar__=__pillar__,
env=env, __env__=env,
sls=sls, __sls__=sls,
**kws) **kws)
if not tmp_data.get('result', False): if not tmp_data.get('result', False):
raise SaltRenderError(tmp_data.get('data', raise SaltRenderError(tmp_data.get('data',

View File

@ -144,7 +144,7 @@ def auto(name):
if line.endswith(' auto mode'): if line.endswith(' auto mode'):
ret['comment'] = '{0} already in auto mode'.format(name) ret['comment'] = '{0} already in auto mode'.format(name)
return ret return ret
ret['changes']['result'] = __salt__['alternatives.auto'](name) ret['changes']['result'] = __salt__['alternatives.auto'](name)
return ret return ret
@ -172,14 +172,14 @@ def set(name, path):
if current == path: if current == path:
ret['comment'] = 'Alternative for {0} already set to {1}'.format(name, path) ret['comment'] = 'Alternative for {0} already set to {1}'.format(name, path)
return ret return ret
display = __salt__['alternatives.display'](name) display = __salt__['alternatives.display'](name)
isinstalled = False isinstalled = False
for line in display.splitlines(): for line in display.splitlines():
if line.startswith(path): if line.startswith(path):
isinstalled = True isinstalled = True
break break
if isinstalled: if isinstalled:
__salt__['alternatives.set'](name, path) __salt__['alternatives.set'](name, path)
current = __salt__['alternatives.show_current'](name) current = __salt__['alternatives.show_current'](name)

View File

@ -64,13 +64,13 @@ In this example ``foo.conf`` in the ``dev`` environment will be used instead.
.. warning:: .. warning::
When using a mode that includes a leading zero you must wrap the When using a mode that includes a leading zero you must wrap the
value in single quotes. If the value is not wrapped in quotes it value in single quotes. If the value is not wrapped in quotes it
will be read by YAML as an integer and evaluated as an octal. will be read by YAML as an integer and evaluated as an octal.
Special files can be managed via the ``mknod`` function. This function will Special files can be managed via the ``mknod`` function. This function will
create and enforce the permissions on a special file. The function supports the create and enforce the permissions on a special file. The function supports the
creation of character devices, block devices, and fifo pipes. The function will creation of character devices, block devices, and fifo pipes. The function will
create the directory structure up to the special file if it is needed on the create the directory structure up to the special file if it is needed on the
minion. The function will not overwrite or operate on (change major/minor minion. The function will not overwrite or operate on (change major/minor
numbers) existing special files with the exception of user, group, and numbers) existing special files with the exception of user, group, and
@ -2468,9 +2468,9 @@ def mknod(name, ntype, major=0, minor=0, user=None, group=None, mode='0600'):
Create a special file similar to the 'nix mknod command. The supported device types are Create a special file similar to the 'nix mknod command. The supported device types are
p (fifo pipe), c (character device), and b (block device). Provide the major and minor p (fifo pipe), c (character device), and b (block device). Provide the major and minor
numbers when specifying a character device or block device. A fifo pipe does not require numbers when specifying a character device or block device. A fifo pipe does not require
this information. The command will create the necessary dirs if needed. If a file of the this information. The command will create the necessary dirs if needed. If a file of the
same name not of the same type/major/minor exists, it will not be overwritten or unlinked same name not of the same type/major/minor exists, it will not be overwritten or unlinked
(deleted). This is logically in place as a safety measure because you can really shoot (deleted). This is logically in place as a safety measure because you can really shoot
yourself in the foot here and it is the behavior of 'nix mknod. It is also important to yourself in the foot here and it is the behavior of 'nix mknod. It is also important to
note that not just anyone can create special devices. Usually this is only done as root. note that not just anyone can create special devices. Usually this is only done as root.
If the state is executed as none other than root on a minion, you may recieve a permision If the state is executed as none other than root on a minion, you may recieve a permision
@ -2509,7 +2509,7 @@ def mknod(name, ntype, major=0, minor=0, user=None, group=None, mode='0600'):
- user: root - user: root
- group: root - group: root
- mode: 660 - mode: 660
/dev/blk: /dev/blk:
file.mknod: file.mknod:
- ntype: b - ntype: b
@ -2518,7 +2518,7 @@ def mknod(name, ntype, major=0, minor=0, user=None, group=None, mode='0600'):
- user: root - user: root
- group: root - group: root
- mode: 660 - mode: 660
/dev/fifo: /dev/fifo:
file.mknod: file.mknod:
- ntype: p - ntype: p

View File

@ -14,12 +14,6 @@ Management of Keystone users.
''' '''
# Import python libs
import sys
# Import salt libs
import salt.utils
def __virtual__(): def __virtual__():
''' '''
@ -144,7 +138,7 @@ def tenant_present(name, description=None, enabled=True):
# Check if user is already present # Check if user is already present
tenant = __salt__['keystone.tenant_get'](name=name) tenant = __salt__['keystone.tenant_get'](name=name)
if 'Error' not in tenant: if 'Error' not in tenant:
if tenant[name]['description'] != description: if tenant[name]['description'] != description:
__salt__['keystone.tenant_update'](name, description, enabled) __salt__['keystone.tenant_update'](name, description, enabled)

View File

@ -38,7 +38,8 @@ def latest(name,
username=None, username=None,
password=None, password=None,
force=False, force=False,
externals=True): externals=True,
trust=False):
''' '''
Checkout or update the working directory to the latest revision from the Checkout or update the working directory to the latest revision from the
remote repository. remote repository.
@ -69,6 +70,9 @@ def latest(name,
externals : True externals : True
Change to False to not checkout or update externals Change to False to not checkout or update externals
trust : False
Automatically trust the remote server. SVN's --trust-server-cert
''' '''
ret = {'name': name, 'result': True, 'comment': '', 'changes': {}} ret = {'name': name, 'result': True, 'comment': '', 'changes': {}}
if not target: if not target:
@ -109,6 +113,9 @@ def latest(name,
if externals is False: if externals is False:
opts += ('--ignore-externals',) opts += ('--ignore-externals',)
if trust:
opts += ('--trust-server-cert',)
if svn_cmd == 'svn.update': if svn_cmd == 'svn.update':
out = __salt__[svn_cmd](cwd, basename, user, username, password, *opts) out = __salt__[svn_cmd](cwd, basename, user, username, password, *opts)
@ -121,6 +128,7 @@ def latest(name,
fmt='dict')[0]['Revision'] fmt='dict')[0]['Revision']
if current_rev != new_rev: if current_rev != new_rev:
ret['changes']['revision'] = "{0} => {1}".format(current_rev, new_rev) ret['changes']['revision'] = "{0} => {1}".format(current_rev, new_rev)
else: else:
out = __salt__[svn_cmd](cwd, name, basename, user, username, password, *opts) out = __salt__[svn_cmd](cwd, name, basename, user, username, password, *opts)

View File

@ -1341,7 +1341,7 @@ def warn_until(version_info,
:param category: The warning class to be thrown, by default :param category: The warning class to be thrown, by default
``DeprecationWarning`` ``DeprecationWarning``
:param stacklevel: There should be no need to set the value of :param stacklevel: There should be no need to set the value of
``stacklevel`` salt should be able to do the right thing ``stacklevel``. Salt should be able to do the right thing.
:param _version_info_: In order to reuse this function for other SaltStack :param _version_info_: In order to reuse this function for other SaltStack
projects, they need to be able to provide the projects, they need to be able to provide the
version info to compare to. version info to compare to.
@ -1380,6 +1380,65 @@ def warn_until(version_info,
warnings.warn(message, category, stacklevel=stacklevel) warnings.warn(message, category, stacklevel=stacklevel)
def kwargs_warn_until(kwargs,
version_info,
category=DeprecationWarning,
stacklevel=None,
_version_info_=None,
_dont_call_warnings=False):
'''
Helper function to raise a warning (by default, a ``DeprecationWarning``)
when unhandled keyword arguments are passed to function, until the
provided ``version_info``, after which, a ``RuntimeError`` will be raised
to remind the developers to remove the ``**kwargs`` because the target
version has been reached.
This function is used to help deprecate unused legacy ``**kwargs`` that
were added to function parameters lists to preserve backwards compatibility
when removing a parameter. See
:doc:`the deprecation development docs </topics/development/deprecations>`
for the modern strategy for deprecating a function parameter.
:param kwargs: The caller's ``**kwargs`` argument value (a ``dict``).
:param version_info: The version info after which the warning becomes a
``RuntimeError``. For example ``(0, 17)``.
:param category: The warning class to be thrown, by default
``DeprecationWarning``
:param stacklevel: There should be no need to set the value of
``stacklevel``. Salt should be able to do the right thing.
:param _version_info_: In order to reuse this function for other SaltStack
projects, they need to be able to provide the
version info to compare to.
:param _dont_call_warnings: This parameter is used just to get the
functionality until the actual error is to be
issued. When we're only after the salt version
checks to raise a ``RuntimeError``.
'''
if not isinstance(version_info, tuple):
raise RuntimeError(
'The \'version_info\' argument should be passed as a tuple.'
)
if stacklevel is None:
# Attribute the warning to the calling function,
# not to kwargs_warn_until() or warn_until()
stacklevel = 3
if _version_info_ is None:
_version_info_ = salt.version.__version_info__
if kwargs or _version_info_ >= version_info:
removal_version = '.'.join(str(component) for component in version_info)
arg_names = ', '.join('\'{0}\''.format(key) for key in kwargs)
warn_until(version_info,
message='The following parameter(s) have been deprecated and '
'will be removed in {0}: {1}.'.format(removal_version, arg_names),
category=category,
stacklevel=stacklevel,
_version_info_=_version_info_,
_dont_call_warnings=_dont_call_warnings
)
def version_cmp(pkg1, pkg2): def version_cmp(pkg1, pkg2):
''' '''
Compares two version strings using distutils.version.LooseVersion. This is Compares two version strings using distutils.version.LooseVersion. This is

View File

@ -162,7 +162,7 @@ def _interfaces_ip(out):
for line in group.splitlines(): for line in group.splitlines():
if not ' ' in line: if not ' ' in line:
continue continue
match = re.match(r'^\d*:\s+([\w.]+)(?:@)?(\w+)?:\s+<(.+)>', line) match = re.match(r'^\d*:\s+([\w.]+)(?:@)?([\w.]+)?:\s+<(.+)>', line)
if match: if match:
iface, parent, attrs = match.groups() iface, parent, attrs = match.groups()
if 'UP' in attrs.split(','): if 'UP' in attrs.split(','):

View File

@ -1422,6 +1422,13 @@ class SaltCallOptionParser(OptionParser, ConfigDirMixIn, MergeConfigMixIn,
help=('Exit with the salt call retcode and not the salt binary ' help=('Exit with the salt call retcode and not the salt binary '
'retcode') 'retcode')
) )
self.add_option(
'--id',
default='',
dest='id',
help=('Specify the minion id to use. If this option is omitted, '
'the id option from the minion config will be used.')
)
def _mixin_after_parsed(self): def _mixin_after_parsed(self):
if not self.args and not self.options.grains_run \ if not self.args and not self.options.grains_run \

View File

@ -135,6 +135,7 @@ class TestDaemon(object):
self.sub_minion_opts = salt.config.minion_config( self.sub_minion_opts = salt.config.minion_config(
os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'sub_minion') os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'sub_minion')
) )
self.sub_minion_opts['root_dir'] = os.path.join(TMP, 'subsalt')
self.sub_minion_opts['user'] = running_tests_user self.sub_minion_opts['user'] = running_tests_user
#if sys.version_info < (2, 7): #if sys.version_info < (2, 7):
# self.sub_minion_opts['multiprocessing'] = False # self.sub_minion_opts['multiprocessing'] = False

View File

@ -200,6 +200,22 @@ sys.stdout.write('cheese')
'hello' == self.run_function( 'hello' == self.run_function(
'cmd.run', ['sleep 1 && echo hello', 'timeout=2'])) 'cmd.run', ['sleep 1 && echo hello', 'timeout=2']))
def test_run_cwd_doesnt_exist_issue_7154(self):
'''
cmd.run should fail and raise
salt.exceptions.CommandExecutionError if the cwd dir does not
exist
'''
from salt.exceptions import CommandExecutionError
import salt.modules.cmdmod as cmdmod
cmd = 'echo OHAI'
cwd = '/path/to/nowhere'
try:
cmdmod.run_all(cmd, cwd=cwd)
except CommandExecutionError:
pass
else:
raise RuntimeError
if __name__ == '__main__': if __name__ == '__main__':
from integration import run_tests from integration import run_tests

View File

@ -318,6 +318,68 @@ class PipStateTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
os.unlink(req_filename) os.unlink(req_filename)
# <---- Using user --------------------------------------------------- # <---- Using user ---------------------------------------------------
def test_issue_6833_pip_upgrade_pip(self):
# Create the testing virtualenv
venv_dir = os.path.join(
integration.TMP, '6833-pip-upgrade-pip'
)
ret = self.run_function('virtualenv.create', [venv_dir])
try:
try:
self.assertEqual(ret['retcode'], 0)
self.assertIn(
'New python executable',
ret['stdout']
)
except AssertionError:
import pprint
pprint.pprint(ret)
raise
# Let's install a fixed version pip over whatever pip was
# previously installed
ret = self.run_function(
'pip.install', ['pip==1.3.1'], upgrade=True,
ignore_installed=True,
bin_env=venv_dir
)
try:
self.assertEqual(ret['retcode'], 0)
self.assertIn(
'Successfully installed pip',
ret['stdout']
)
except AssertionError:
import pprint
pprint.pprint(ret)
raise
# Le't make sure we have pip 1.3.1 installed
self.assertEqual(
self.run_function('pip.list', ['pip'], bin_env=venv_dir),
{'pip': '1.3.1'}
)
# Now the actual pip upgrade pip test
ret = self.run_state(
'pip.installed', name='pip==1.4.1', upgrade=True,
bin_env=venv_dir
)
try:
self.assertSaltTrueReturn(ret)
self.assertInSaltReturn(
'Installed',
ret,
['changes', 'pip==1.4.1']
)
except AssertionError:
import pprint
pprint.pprint(ret)
raise
finally:
if os.path.isdir(venv_dir):
shutil.rmtree(venv_dir)
if __name__ == '__main__': if __name__ == '__main__':
from integration import run_tests from integration import run_tests

View File

@ -783,14 +783,14 @@ class PipTestCase(TestCase):
'pycrypto==2.6' 'pycrypto==2.6'
] ]
mock = MagicMock( mock = MagicMock(
return_value={ side_effect=[
'retcode': 0, {'retcode': 0, 'stdout': 'pip MOCKED_VERSION'},
'stdout': '\n'.join(eggs) {'retcode': 0, 'stdout': '\n'.join(eggs)}
} ]
) )
with patch.dict(pip.__salt__, {'cmd.run_all': mock}): with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
ret = pip.list_() ret = pip.list_()
mock.assert_called_once_with( mock.assert_called_with(
'pip freeze', 'pip freeze',
runas=None, runas=None,
cwd=None cwd=None
@ -801,6 +801,7 @@ class PipTestCase(TestCase):
'M2Crypto': '0.21.1', 'M2Crypto': '0.21.1',
'bbfreeze-loader': '1.1.0', 'bbfreeze-loader': '1.1.0',
'bbfreeze': '1.1.0', 'bbfreeze': '1.1.0',
'pip': 'MOCKED_VERSION',
'pycrypto': '2.6' 'pycrypto': '2.6'
} }
) )
@ -829,7 +830,7 @@ class PipTestCase(TestCase):
) )
with patch.dict(pip.__salt__, {'cmd.run_all': mock}): with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
ret = pip.list_(prefix='bb') ret = pip.list_(prefix='bb')
mock.assert_called_once_with( mock.assert_called_with(
'pip freeze', 'pip freeze',
runas=None, runas=None,
cwd=None cwd=None
@ -923,7 +924,7 @@ class PipTestCase(TestCase):
warnings.resetwarnings() warnings.resetwarnings()
warnings.filterwarnings('always', '', DeprecationWarning, __name__) warnings.filterwarnings('always', '', DeprecationWarning, __name__)
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''}) mock = MagicMock(return_value={'retcode': 0, 'stdout': 'pip VERSION'})
with patch.dict(pip.__salt__, {'cmd.run_all': mock}): with patch.dict(pip.__salt__, {'cmd.run_all': mock}):
with warnings.catch_warnings(record=True) as w: with warnings.catch_warnings(record=True) as w:
pip.list_('blah', runas='me!') pip.list_('blah', runas='me!')

View File

@ -3,7 +3,7 @@
tests.unit.utils.warnings_test tests.unit.utils.warnings_test
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Test ``salt.utils.warn_until`` Test ``salt.utils.warn_until`` and ``salt.utils.kwargs_warn_until``
:codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)` :codeauthor: :email:`Pedro Algarvio (pedro@algarvio.me)`
:copyright: © 2013 by the SaltStack Team, see AUTHORS for more details. :copyright: © 2013 by the SaltStack Team, see AUTHORS for more details.
@ -20,13 +20,13 @@ from salttesting.mock import NO_MOCK, NO_MOCK_REASON, patch
ensure_in_syspath('../../') ensure_in_syspath('../../')
# Import salt libs # Import salt libs
from salt.utils import warn_until from salt.utils import warn_until, kwargs_warn_until
@skipIf(NO_MOCK, NO_MOCK_REASON) @skipIf(NO_MOCK, NO_MOCK_REASON)
class WarnUntilTestCase(TestCase): class WarnUntilTestCase(TestCase):
@patch('salt.version') @patch('salt.version')
def test_warning_raised(self, salt_version_mock): def test_warn_until_warning_raised(self, salt_version_mock):
# We *always* want *all* warnings thrown on this module # We *always* want *all* warnings thrown on this module
warnings.filterwarnings('always', '', DeprecationWarning, __name__) warnings.filterwarnings('always', '', DeprecationWarning, __name__)
@ -75,6 +75,54 @@ class WarnUntilTestCase(TestCase):
(0, 17), 'Foo', _dont_call_warnings=True (0, 17), 'Foo', _dont_call_warnings=True
) )
@patch('salt.version')
def test_kwargs_warn_until_warning_raised(self, salt_version_mock):
# We *always* want *all* warnings thrown on this module
warnings.filterwarnings('always', '', DeprecationWarning, __name__)
# Define a salt version info
salt_version_mock.__version_info__ = (0, 16)
def raise_warning(**kwargs):
kwargs_warn_until(
kwargs,
(0, 17),
)
# raise_warning({...}) should show warning until version info is >= (0, 17)
with warnings.catch_warnings(record=True) as recorded_warnings:
raise_warning(foo=42) # with a kwarg
self.assertEqual(
'The following parameter(s) have been deprecated and '
'will be removed in 0.17: \'foo\'.',
str(recorded_warnings[0].message)
)
# With no **kwargs, should not show warning until version info is >= (0, 17)
with warnings.catch_warnings(record=True) as recorded_warnings:
kwargs_warn_until(
{}, # no kwargs
(0, 17),
)
self.assertEqual(0, len(recorded_warnings))
# Let's set version info to (0, 17), a RuntimeError should be raised
# regardless of whether or not we pass any **kwargs.
salt_version_mock.__version_info__ = (0, 17)
with self.assertRaisesRegexp(
RuntimeError,
r'The warning triggered on filename \'(.*)warnings_test.py\', '
r'line number ([\d]+), is supposed to be shown until version '
r'\'0.17\' is released. Current version is now \'0.17\'. Please '
r'remove the warning.'):
raise_warning() # no kwargs
with self.assertRaisesRegexp(
RuntimeError,
r'The warning triggered on filename \'(.*)warnings_test.py\', '
r'line number ([\d]+), is supposed to be shown until version '
r'\'0.17\' is released. Current version is now \'0.17\'. Please '
r'remove the warning.'):
raise_warning(bar='baz', qux='quux') # some kwargs
if __name__ == '__main__': if __name__ == '__main__':
from integration import run_tests from integration import run_tests