mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #27521 from terminalmage/zh107
Remove raw string formatting in execution modules
This commit is contained in:
commit
59e93ddde6
@ -17,10 +17,6 @@ import os
|
||||
import re
|
||||
import logging
|
||||
import json
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
|
||||
# Import third party libs
|
||||
import yaml
|
||||
@ -181,8 +177,11 @@ def _get_virtual():
|
||||
__context__['pkg._get_virtual'][realpkg] = []
|
||||
__context__['pkg._get_virtual'][realpkg].append(pkg.name)
|
||||
elif _has_dctrl_tools():
|
||||
cmd = 'grep-available -F Provides -s Package,Provides -e "^.+$"'
|
||||
out = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')
|
||||
cmd = ['grep-available', '-F', 'Provides', '-s',
|
||||
'Package,Provides', '-e', '^.+$']
|
||||
out = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
virtpkg_re = re.compile(r'Package: (\S+)\nProvides: ([\S, ]+)')
|
||||
for realpkg, provides in virtpkg_re.findall(out):
|
||||
__context__['pkg._get_virtual'][realpkg] = provides.split(', ')
|
||||
@ -241,7 +240,7 @@ def latest_version(*names, **kwargs):
|
||||
ret[name] = ''
|
||||
pkgs = list_pkgs(versions_as_list=True)
|
||||
repo = ['-o', 'APT::Default-Release={0}'.format(fromrepo)] \
|
||||
if fromrepo else ''
|
||||
if fromrepo else None
|
||||
|
||||
# Refresh before looking for the latest version available
|
||||
if refresh:
|
||||
@ -254,10 +253,11 @@ def latest_version(*names, **kwargs):
|
||||
|
||||
for name in names:
|
||||
cmd = ['apt-cache', '-q', 'policy', name]
|
||||
if isinstance(repo, list):
|
||||
cmd = cmd + repo
|
||||
out = __salt__['cmd.run_all'](cmd, python_shell=False,
|
||||
output_loglevel='trace')
|
||||
if repo is not None:
|
||||
cmd.extend(repo)
|
||||
out = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
candidate = ''
|
||||
for line in out['stdout'].splitlines():
|
||||
if 'Candidate' in line:
|
||||
@ -335,8 +335,10 @@ def refresh_db():
|
||||
salt '*' pkg.refresh_db
|
||||
'''
|
||||
ret = {}
|
||||
cmd = 'apt-get -q update'
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
cmd = ['apt-get', '-q', 'update']
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
if 'stderr' in call:
|
||||
@ -666,7 +668,7 @@ def install(name=None,
|
||||
env.update(DPKG_ENV_VARS.copy())
|
||||
|
||||
for cmd in cmds:
|
||||
__salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
@ -704,8 +706,8 @@ def _uninstall(action='remove', name=None, pkgs=None, **kwargs):
|
||||
__salt__['cmd.run'](
|
||||
cmd,
|
||||
env=env,
|
||||
output_loglevel='trace',
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
@ -1267,12 +1269,6 @@ def version_cmp(pkg1, pkg2):
|
||||
|
||||
salt '*' pkg.version_cmp '0.2.4-0ubuntu1' '0.2.4.1-0ubuntu1'
|
||||
'''
|
||||
# both apt_pkg.version_compare and _cmd_quote need string arguments.
|
||||
pkg1 = str(pkg1)
|
||||
pkg2 = str(pkg2)
|
||||
|
||||
# if we have apt_pkg, this will be quickier this way
|
||||
# and also do not rely on shell.
|
||||
if HAS_APTPKG:
|
||||
try:
|
||||
# the apt_pkg module needs to be manually initialized
|
||||
@ -1282,23 +1278,21 @@ def version_cmp(pkg1, pkg2):
|
||||
# return an int representing the difference in minor versions, or
|
||||
# 1/-1 if the difference is smaller than minor versions. normalize
|
||||
# to -1, 0 or 1.
|
||||
try:
|
||||
ret = apt_pkg.version_compare(pkg1, pkg2)
|
||||
if ret > 0:
|
||||
return 1
|
||||
if ret < 0:
|
||||
return -1
|
||||
return 0
|
||||
except (TypeError, ValueError):
|
||||
# try to use shell version in case of errors via
|
||||
# the python binding
|
||||
except TypeError:
|
||||
ret = apt_pkg.version_compare(str(pkg1), str(pkg2))
|
||||
return 1 if ret > 0 else -1 if ret < 0 else 0
|
||||
except Exception:
|
||||
# Try to use shell version in case of errors w/python bindings
|
||||
pass
|
||||
try:
|
||||
for oper, ret in (('lt', -1), ('eq', 0), ('gt', 1)):
|
||||
cmd = 'dpkg --compare-versions {0} {1} ' \
|
||||
'{2}'.format(_cmd_quote(pkg1), oper, _cmd_quote(pkg2))
|
||||
retcode = __salt__['cmd.retcode'](
|
||||
cmd, output_loglevel='trace', ignore_retcode=True
|
||||
)
|
||||
cmd = ['dpkg', '--compare-versions', pkg1, oper, pkg2]
|
||||
retcode = __salt__['cmd.retcode'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False,
|
||||
ignore_retcode=True)
|
||||
if retcode == 0:
|
||||
return ret
|
||||
except Exception as exc:
|
||||
@ -1319,8 +1313,12 @@ def _consolidate_repo_sources(sources):
|
||||
Consolidate APT sources.
|
||||
'''
|
||||
if not isinstance(sources, sourceslist.SourcesList):
|
||||
raise TypeError('{0!r} not a {1!r}'.format(type(sources),
|
||||
sourceslist.SourcesList))
|
||||
raise TypeError(
|
||||
'\'{0}\' not a \'{1}\''.format(
|
||||
type(sources),
|
||||
sourceslist.SourcesList
|
||||
)
|
||||
)
|
||||
|
||||
consolidated = {}
|
||||
delete_files = set()
|
||||
@ -1438,7 +1436,7 @@ def get_repo(repo, **kwargs):
|
||||
uri_match.group(2))
|
||||
except SyntaxError:
|
||||
raise CommandExecutionError(
|
||||
'Error: repo {0!r} is not a well formatted definition'
|
||||
'Error: repo \'{0}\' is not a well formatted definition'
|
||||
.format(repo)
|
||||
)
|
||||
|
||||
@ -1662,15 +1660,21 @@ def mod_repo(repo, saltenv='base', **kwargs):
|
||||
return {repo: repo_info}
|
||||
else:
|
||||
if float(__grains__['osrelease']) < 12.04:
|
||||
cmd = 'apt-add-repository {0}'.format(_cmd_quote(repo))
|
||||
cmd = ['apt-add-repository', repo]
|
||||
else:
|
||||
cmd = 'apt-add-repository -y {0}'.format(_cmd_quote(repo))
|
||||
out = __salt__['cmd.run_all'](cmd, **kwargs)
|
||||
cmd = ['apt-add-repository', '-y', repo]
|
||||
out = __salt__['cmd.run_all'](cmd,
|
||||
python_shell=False,
|
||||
**kwargs)
|
||||
if out['retcode']:
|
||||
raise CommandExecutionError(
|
||||
'Unable to add PPA {0!r}. '
|
||||
'{1!r} exited with status {2!s}: '
|
||||
'{3!r} '.format(repo[4:], cmd, out['retcode'], out['stderr'])
|
||||
'Unable to add PPA \'{0}\'. \'{1}\' exited with '
|
||||
'status {2!s}: \'{3}\' '.format(
|
||||
repo[4:],
|
||||
cmd,
|
||||
out['retcode'],
|
||||
out['stderr']
|
||||
)
|
||||
)
|
||||
# explicit refresh when a repo is modified.
|
||||
if kwargs.get('refresh_db', True):
|
||||
@ -1690,7 +1694,7 @@ def mod_repo(repo, saltenv='base', **kwargs):
|
||||
'Unable to get PPA info from argument. '
|
||||
'Expected format "<PPA_OWNER>/<PPA_NAME>" '
|
||||
'(e.g. saltstack/salt) not found. Received '
|
||||
'{0!r} instead.'.format(repo[4:])
|
||||
'\'{0}\' instead.'.format(repo[4:])
|
||||
)
|
||||
dist = __grains__['lsb_distrib_codename']
|
||||
# ppa has a lot of implicit arguments. Make them explicit.
|
||||
@ -1770,7 +1774,7 @@ def mod_repo(repo, saltenv='base', **kwargs):
|
||||
repo_type, repo_uri, repo_dist, repo_comps = _split_repo_str(repo)
|
||||
except SyntaxError:
|
||||
raise SyntaxError(
|
||||
'Error: repo {0!r} not a well formatted definition'.format(repo)
|
||||
'Error: repo \'{0}\' not a well formatted definition'.format(repo)
|
||||
)
|
||||
|
||||
full_comp_list = set(repo_comps)
|
||||
@ -1783,15 +1787,15 @@ def mod_repo(repo, saltenv='base', **kwargs):
|
||||
raise NameError(error_str)
|
||||
if isinstance(keyid, int): # yaml can make this an int, we need the hex version
|
||||
keyid = hex(keyid)
|
||||
cmd = 'apt-key export {0}'.format(_cmd_quote(keyid))
|
||||
output = __salt__['cmd.run_stdout'](cmd, **kwargs)
|
||||
cmd = ['apt-key', 'export', keyid]
|
||||
output = __salt__['cmd.run_stdout'](cmd, python_shell=False, **kwargs)
|
||||
imported = output.startswith('-----BEGIN PGP')
|
||||
if keyserver:
|
||||
if not imported:
|
||||
cmd = ('apt-key adv --keyserver {0} --logger-fd 1 '
|
||||
'--recv-keys {1}')
|
||||
ret = __salt__['cmd.run_all'](cmd.format(_cmd_quote(keyserver),
|
||||
_cmd_quote(keyid)),
|
||||
cmd = ['apt-key', 'adv', '--keyserver', keyserver,
|
||||
'--logger-fd', '1', '--recv-keys', keyid]
|
||||
ret = __salt__['cmd.run_all'](cmd,
|
||||
python_shell=False,
|
||||
**kwargs)
|
||||
if ret['retcode'] != 0:
|
||||
raise CommandExecutionError(
|
||||
@ -1806,11 +1810,11 @@ def mod_repo(repo, saltenv='base', **kwargs):
|
||||
raise CommandExecutionError(
|
||||
'Error: file not found: {0}'.format(key_url)
|
||||
)
|
||||
cmd = 'apt-key add {0}'.format(_cmd_quote(fn_))
|
||||
out = __salt__['cmd.run_stdout'](cmd, **kwargs)
|
||||
cmd = ['apt-key', 'add', fn_]
|
||||
out = __salt__['cmd.run_stdout'](cmd, python_shell=False, **kwargs)
|
||||
if not out.upper().startswith('OK'):
|
||||
raise CommandExecutionError(
|
||||
'Error: key retrieval failed: {0}'.format(cmd.format(key_url))
|
||||
'Error: failed to add key from {0}'.format(key_url)
|
||||
)
|
||||
|
||||
if 'comps' in kwargs:
|
||||
@ -2016,12 +2020,11 @@ def get_selections(pattern=None, state=None):
|
||||
salt '*' pkg.get_selections 'openssh*' state=hold
|
||||
'''
|
||||
ret = {}
|
||||
cmd = 'dpkg --get-selections'
|
||||
if pattern:
|
||||
cmd += ' {0!r}'.format(_cmd_quote(pattern))
|
||||
else:
|
||||
cmd += ' "*"'
|
||||
stdout = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')
|
||||
cmd = ['dpkg', '--get-selections']
|
||||
cmd.append(pattern if pattern else '*')
|
||||
stdout = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
ret = _parse_selections(stdout)
|
||||
if state:
|
||||
return {state: ret.get(state, [])}
|
||||
@ -2207,10 +2210,11 @@ def owner(*paths):
|
||||
if not paths:
|
||||
return ''
|
||||
ret = {}
|
||||
cmd = 'dpkg -S {0!r}'
|
||||
for path in paths:
|
||||
output = __salt__['cmd.run_stdout'](cmd.format(_cmd_quote(path)),
|
||||
output_loglevel='trace')
|
||||
cmd = ['dpkg', '-S', path]
|
||||
output = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
ret[path] = output.split(':')[0]
|
||||
if 'no path found' in ret[path].lower():
|
||||
ret[path] = ''
|
||||
|
@ -16,6 +16,7 @@ import datetime
|
||||
# pylint: disable=import-error,redefined-builtin
|
||||
from salt.ext.six.moves import map
|
||||
# pylint: enable=import-error,redefined-builtin
|
||||
from salt.exceptions import CommandNotFoundError
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
@ -40,11 +41,12 @@ def _cmd(binary, *args):
|
||||
'''
|
||||
Wrapper to run at(1) or return None.
|
||||
'''
|
||||
# TODO: Use CommandNotFoundException for this
|
||||
binary = salt.utils.which(binary)
|
||||
if binary:
|
||||
return __salt__['cmd.run_stdout']('{0} {1}'.format(binary,
|
||||
' '.join(args)))
|
||||
if not binary:
|
||||
raise CommandNotFoundError('{0}: command not found'.format(binary))
|
||||
cmd = [binary] + list(args)
|
||||
return __salt__['cmd.run_stdout']([binary] + list(args),
|
||||
python_shell=False)
|
||||
|
||||
|
||||
def atq(tag=None):
|
||||
@ -211,10 +213,10 @@ def at(*args, **kwargs): # pylint: disable=C0103
|
||||
stdin = ' '.join(args[1:])
|
||||
cmd = [binary, args[0]]
|
||||
|
||||
cmd_kwargs = {'stdin': stdin, 'python_shell': False}
|
||||
if 'runas' in kwargs:
|
||||
output = __salt__['cmd.run'](cmd, stdin=stdin, python_shell=False, runas=kwargs['runas'])
|
||||
else:
|
||||
output = __salt__['cmd.run'](cmd, stdin=stdin, python_shell=False)
|
||||
cmd_kwargs['runas'] = kwargs['runas']
|
||||
output = __salt__['cmd.run'](cmd, **cmd_kwargs)
|
||||
|
||||
if output is None:
|
||||
return '\'at.at\' is not available.'
|
||||
@ -255,7 +257,7 @@ def atc(jobid):
|
||||
if output is None:
|
||||
return '\'at.atc\' is not available.'
|
||||
elif output == '':
|
||||
return {'error': 'invalid job id {0!r}'.format(jobid)}
|
||||
return {'error': 'invalid job id \'{0}\''.format(jobid)}
|
||||
|
||||
return output
|
||||
|
||||
|
@ -10,6 +10,11 @@ try:
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# Import salt libs
|
||||
import salt.ext.six as six
|
||||
import salt.utils
|
||||
from salt.exceptions import SaltInvocationError
|
||||
|
||||
# Define the module's virtual name
|
||||
__virtualname__ = 'shadow'
|
||||
|
||||
@ -51,30 +56,47 @@ def info(name):
|
||||
'name': '',
|
||||
'passwd': ''}
|
||||
|
||||
cmd = ""
|
||||
if __salt__['cmd.has_exec']('pw'):
|
||||
cmd = 'pw user show {0}'.format(name)
|
||||
elif __grains__['kernel'] in ('NetBSD', 'OpenBSD'):
|
||||
cmd = 'grep "^{0}:" /etc/master.passwd'.format(name)
|
||||
if not isinstance(name, six.string_types):
|
||||
name = str(name)
|
||||
if ':' in name:
|
||||
raise SaltInvocationError('Invalid username \'{0}\''.format(name))
|
||||
|
||||
if cmd:
|
||||
cmd += '| cut -f6,7 -d:'
|
||||
if __salt__['cmd.has_exec']('pw'):
|
||||
change, expire = __salt__['cmd.run_stdout'](
|
||||
['pw', 'user', 'show', name],
|
||||
python_shell=False).split(':')[5:7]
|
||||
elif __grains__['kernel'] in ('NetBSD', 'OpenBSD'):
|
||||
try:
|
||||
change, expire = __salt__['cmd.run_all'](cmd, python_shell=True)['stdout'].split(':')
|
||||
with salt.utils.fopen('/etc/master.passwd', 'r') as fp_:
|
||||
for line in fp_:
|
||||
if line.startswith('{0}:'.format(name)):
|
||||
change, expire = line.rstrip('\n')[5:7]
|
||||
break
|
||||
except IOError:
|
||||
change = expire = None
|
||||
else:
|
||||
change = expire = None
|
||||
|
||||
try:
|
||||
ret['change'] = int(change)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
ret['change'] = int(change)
|
||||
|
||||
try:
|
||||
ret['expire'] = int(expire)
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def set_change(name, change):
|
||||
'''
|
||||
Sets the time at which the password expires (in seconds since the EPOCH).
|
||||
See man usermod on NetBSD and OpenBSD or man pw on FreeBSD.
|
||||
"0" means the password never expires.
|
||||
Sets the time at which the password expires (in seconds since the UNIX
|
||||
epoch). See ``man 8 usermod`` on NetBSD and OpenBSD or ``man 8 pw`` on
|
||||
FreeBSD.
|
||||
|
||||
A value of ``0`` sets the password to never expire.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -86,10 +108,10 @@ def set_change(name, change):
|
||||
if change == pre_info['change']:
|
||||
return True
|
||||
if __grains__['kernel'] == 'FreeBSD':
|
||||
cmd = 'pw user mod {0} -f {1}'.format(name, change)
|
||||
cmd = ['pw', 'user', 'mod', name, '-f', change]
|
||||
else:
|
||||
cmd = 'usermod -f {0} {1}'.format(change, name)
|
||||
__salt__['cmd.run'](cmd)
|
||||
cmd = ['usermod', '-f', change, name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['change'] != pre_info['change']:
|
||||
return post_info['change'] == change
|
||||
@ -97,9 +119,11 @@ def set_change(name, change):
|
||||
|
||||
def set_expire(name, expire):
|
||||
'''
|
||||
Sets the time at which the account expires (in seconds since the EPOCH).
|
||||
See man usermod on NetBSD and OpenBSD or man pw on FreeBSD.
|
||||
"0" means the account never expires.
|
||||
Sets the time at which the account expires (in seconds since the UNIX
|
||||
epoch). See ``man 8 usermod`` on NetBSD and OpenBSD or ``man 8 pw`` on
|
||||
FreeBSD.
|
||||
|
||||
A value of ``0`` sets the account to never expire.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -111,10 +135,10 @@ def set_expire(name, expire):
|
||||
if expire == pre_info['expire']:
|
||||
return True
|
||||
if __grains__['kernel'] == 'FreeBSD':
|
||||
cmd = 'pw user mod {0} -e {1}'.format(name, expire)
|
||||
cmd = ['pw', 'user', 'mod', name, '-e', expire]
|
||||
else:
|
||||
cmd = 'usermod -e {0} {1}'.format(expire, name)
|
||||
__salt__['cmd.run'](cmd)
|
||||
cmd = ['usermod', '-e', expire, name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['expire'] != pre_info['expire']:
|
||||
return post_info['expire'] == expire
|
||||
@ -127,8 +151,9 @@ def set_password(name, password):
|
||||
|
||||
``python -c "import crypt; print crypt.crypt('password', ciphersalt)"``
|
||||
|
||||
:strong:`NOTE:` When constructing the ``ciphersalt`` string, you must
|
||||
escape any dollar signs, to avoid them being interpolated by the shell.
|
||||
.. note::
|
||||
When constructing the ``ciphersalt`` string, you must escape any dollar
|
||||
signs, to avoid them being interpolated by the shell.
|
||||
|
||||
``'password'`` is, of course, the password for which you want to generate
|
||||
a hash.
|
||||
@ -148,10 +173,13 @@ def set_password(name, password):
|
||||
salt '*' shadow.set_password someuser '$1$UYCIxa628.9qXjpQCjM4a..'
|
||||
'''
|
||||
if __grains__.get('os', '') == 'FreeBSD':
|
||||
cmd = 'pw user mod {0} -H 0'.format(name)
|
||||
cmd = ['pw', 'user', 'mod', name, '-H', '0']
|
||||
stdin = password
|
||||
else:
|
||||
cmd = 'usermod -p {0!r} {1}'.format(password, name)
|
||||
cmd = ['usermod', '-p', password, name]
|
||||
stdin = None
|
||||
__salt__['cmd.run'](cmd, stdin=stdin, output_loglevel='quiet')
|
||||
__salt__['cmd.run'](cmd,
|
||||
stdin=stdin,
|
||||
output_loglevel='quiet',
|
||||
python_shell=False)
|
||||
return info(name)['passwd'] == password
|
||||
|
@ -25,11 +25,11 @@ from salt.utils import vt
|
||||
import salt.utils
|
||||
import salt.utils.timed_subprocess
|
||||
import salt.grains.extra
|
||||
from salt.ext.six import string_types
|
||||
import salt.ext.six as six
|
||||
from salt.exceptions import CommandExecutionError, TimedProcTimeoutError
|
||||
from salt.log import LOG_LEVELS
|
||||
import salt.ext.six as six
|
||||
from salt.ext.six.moves import range
|
||||
from salt.ext.six.moves import shlex_quote as _cmd_quote
|
||||
|
||||
# Only available on POSIX systems, nonfatal on windows
|
||||
try:
|
||||
@ -156,7 +156,7 @@ def _check_loglevel(level='info', quiet=False):
|
||||
'''
|
||||
def _bad_level(level):
|
||||
log.error(
|
||||
'Invalid output_loglevel {0!r}. Valid levels are: {1}. Falling '
|
||||
'Invalid output_loglevel \'{0}\'. Valid levels are: {1}. Falling '
|
||||
'back to \'info\'.'
|
||||
.format(
|
||||
level,
|
||||
@ -290,7 +290,7 @@ def _run(cmd,
|
||||
env = _parse_env(env)
|
||||
|
||||
for bad_env_key in (x for x, y in six.iteritems(env) if y is None):
|
||||
log.error('Environment variable {0!r} passed without a value. '
|
||||
log.error('Environment variable \'{0}\' passed without a value. '
|
||||
'Setting value to an empty string'.format(bad_env_key))
|
||||
env[bad_env_key] = ''
|
||||
|
||||
@ -305,7 +305,7 @@ def _run(cmd,
|
||||
pwd.getpwnam(runas)
|
||||
except KeyError:
|
||||
raise CommandExecutionError(
|
||||
'User {0!r} is not available'.format(runas)
|
||||
'User \'{0}\' is not available'.format(runas)
|
||||
)
|
||||
try:
|
||||
# Getting the environment for the runas user
|
||||
@ -343,7 +343,7 @@ def _run(cmd,
|
||||
env[key] = val.encode(fse)
|
||||
except ValueError:
|
||||
raise CommandExecutionError(
|
||||
'Environment could not be retrieved for User {0!r}'.format(
|
||||
'Environment could not be retrieved for User \'{0}\''.format(
|
||||
runas
|
||||
)
|
||||
)
|
||||
@ -353,8 +353,11 @@ def _run(cmd,
|
||||
# requested. The command output is what will be controlled by the
|
||||
# 'loglevel' parameter.
|
||||
msg = (
|
||||
'Executing command {0!r} {1}in directory {2!r}'.format(
|
||||
cmd, 'as user {0!r} '.format(runas) if runas else '', cwd
|
||||
'Executing command {0}{1}{0} {2}in directory \'{3}\''.format(
|
||||
'\'' if not isinstance(cmd, list) else '',
|
||||
cmd,
|
||||
'as user \'{0}\' '.format(runas) if runas else '',
|
||||
cwd
|
||||
)
|
||||
)
|
||||
log.info(log_callback(msg))
|
||||
@ -418,7 +421,7 @@ def _run(cmd,
|
||||
|
||||
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'
|
||||
'Specified cwd \'{0}\' either not absolute or does not exist'
|
||||
.format(cwd)
|
||||
)
|
||||
|
||||
@ -433,8 +436,8 @@ def _run(cmd,
|
||||
proc = salt.utils.timed_subprocess.TimedProc(cmd, **kwargs)
|
||||
except (OSError, IOError) as exc:
|
||||
raise CommandExecutionError(
|
||||
'Unable to run command {0!r} with the context {1!r}, reason: {2}'
|
||||
.format(cmd, kwargs, exc)
|
||||
'Unable to run command \'{0}\' with the context \'{1}\', '
|
||||
'reason: {2}'.format(cmd, kwargs, exc)
|
||||
)
|
||||
|
||||
try:
|
||||
@ -832,8 +835,10 @@ def run(cmd,
|
||||
if lvl < LOG_LEVELS['error']:
|
||||
lvl = LOG_LEVELS['error']
|
||||
msg = (
|
||||
'Command {0!r} failed with return code: {1}'
|
||||
.format(cmd, ret['retcode'])
|
||||
'Command \'{0}\' failed with return code: {1}'.format(
|
||||
cmd,
|
||||
ret['retcode']
|
||||
)
|
||||
)
|
||||
log.error(log_callback(msg))
|
||||
log.log(lvl, 'output: {0}'.format(log_callback(ret['stdout'])))
|
||||
@ -1194,8 +1199,10 @@ def run_stdout(cmd,
|
||||
if lvl < LOG_LEVELS['error']:
|
||||
lvl = LOG_LEVELS['error']
|
||||
msg = (
|
||||
'Command {0!r} failed with return code: {1}'
|
||||
.format(cmd, ret['retcode'])
|
||||
'Command \'{0}\' failed with return code: {1}'.format(
|
||||
cmd,
|
||||
ret['retcode']
|
||||
)
|
||||
)
|
||||
log.error(log_callback(msg))
|
||||
if ret['stdout']:
|
||||
@ -1376,8 +1383,10 @@ def run_stderr(cmd,
|
||||
if lvl < LOG_LEVELS['error']:
|
||||
lvl = LOG_LEVELS['error']
|
||||
msg = (
|
||||
'Command {0!r} failed with return code: {1}'
|
||||
.format(cmd, ret['retcode'])
|
||||
'Command \'{0}\' failed with return code: {1}'.format(
|
||||
cmd,
|
||||
ret['retcode']
|
||||
)
|
||||
)
|
||||
log.error(log_callback(msg))
|
||||
if ret['stdout']:
|
||||
@ -1558,8 +1567,10 @@ def run_all(cmd,
|
||||
if lvl < LOG_LEVELS['error']:
|
||||
lvl = LOG_LEVELS['error']
|
||||
msg = (
|
||||
'Command {0!r} failed with return code: {1}'
|
||||
.format(cmd, ret['retcode'])
|
||||
'Command \'{0}\' failed with return code: {1}'.format(
|
||||
cmd,
|
||||
ret['retcode']
|
||||
)
|
||||
)
|
||||
log.error(log_callback(msg))
|
||||
if ret['stdout']:
|
||||
@ -1741,8 +1752,10 @@ def retcode(cmd,
|
||||
if lvl < LOG_LEVELS['error']:
|
||||
lvl = LOG_LEVELS['error']
|
||||
msg = (
|
||||
'Command {0!r} failed with return code: {1}'
|
||||
.format(cmd, ret['retcode'])
|
||||
'Command \'{0}\' failed with return code: {1}'.format(
|
||||
cmd,
|
||||
ret['retcode']
|
||||
)
|
||||
)
|
||||
log.error(log_callback(msg))
|
||||
log.log(lvl, 'output: {0}'.format(log_callback(ret['stdout'])))
|
||||
@ -1938,10 +1951,14 @@ def script(source,
|
||||
try:
|
||||
os.remove(path)
|
||||
except (IOError, OSError) as exc:
|
||||
log.error('cmd.script: Unable to clean tempfile {0!r}: {1}'
|
||||
.format(path, exc))
|
||||
log.error(
|
||||
'cmd.script: Unable to clean tempfile \'{0}\': {1}'.format(
|
||||
path,
|
||||
exc
|
||||
)
|
||||
)
|
||||
|
||||
if isinstance(__env__, string_types):
|
||||
if isinstance(__env__, six.string_types):
|
||||
salt.utils.warn_until(
|
||||
'Boron',
|
||||
'Passing a salt environment should be done using \'saltenv\' not '
|
||||
@ -2416,7 +2433,7 @@ def run_chroot(root,
|
||||
|
||||
if isinstance(cmd, (list, tuple)):
|
||||
cmd = ' '.join([str(i) for i in cmd])
|
||||
cmd = 'chroot {0} {1} -c {2!r}'.format(root, sh_, cmd)
|
||||
cmd = 'chroot {0} {1} -c {2}'.format(root, sh_, _cmd_quote(cmd))
|
||||
|
||||
run_func = __context__.pop('cmd.run_chroot.func', run_all)
|
||||
|
||||
|
@ -7,10 +7,15 @@ from __future__ import absolute_import
|
||||
# Import python libs
|
||||
import logging
|
||||
import os.path
|
||||
import shlex
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
from salt.exceptions import CommandExecutionError, CommandNotFoundError, SaltInvocationError
|
||||
from salt.exceptions import (
|
||||
CommandExecutionError,
|
||||
CommandNotFoundError,
|
||||
SaltInvocationError
|
||||
)
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -56,7 +61,7 @@ def did_composer_install(dir):
|
||||
|
||||
|
||||
def _run_composer(action,
|
||||
dir=None,
|
||||
directory=None,
|
||||
composer=None,
|
||||
php=None,
|
||||
runas=None,
|
||||
@ -79,7 +84,7 @@ def _run_composer(action,
|
||||
action
|
||||
The action to pass to composer ('install', 'update', 'selfupdate', etc).
|
||||
|
||||
dir
|
||||
directory
|
||||
Directory location of the composer.json file. Required except when
|
||||
action='selfupdate'
|
||||
|
||||
@ -130,53 +135,55 @@ def _run_composer(action,
|
||||
|
||||
# Validate Composer is there
|
||||
if not _valid_composer(composer):
|
||||
raise CommandNotFoundError('\'composer.{0}\' is not available. Couldn\'t find {1!r}.'
|
||||
.format(action, composer))
|
||||
|
||||
# Don't need a dir for the 'selfupdate' action; all other actions do need a dir
|
||||
if dir is None and action != 'selfupdate':
|
||||
raise SaltInvocationError('{0!r} is required for \'composer.{1}\''
|
||||
.format('dir', action))
|
||||
raise CommandNotFoundError(
|
||||
'\'composer.{0}\' is not available. Couldn\'t find \'{1}\'.'
|
||||
.format(action, composer)
|
||||
)
|
||||
|
||||
if action is None:
|
||||
raise SaltInvocationError('{0!r} is required for {1!r}'
|
||||
.format('action', 'composer._run_composer'))
|
||||
raise SaltInvocationError('The \'action\' argument is required')
|
||||
|
||||
# Don't need a dir for the 'selfupdate' action; all other actions do need a dir
|
||||
if directory is None and action != 'selfupdate':
|
||||
raise SaltInvocationError(
|
||||
'The \'directory\' argument is required for composer.{0}'.format(action)
|
||||
)
|
||||
|
||||
# Base Settings
|
||||
cmd = '{0} {1} {2}'.format(composer, action, '--no-interaction --no-ansi')
|
||||
cmd = [composer, action, '--no-interaction', '--no-ansi']
|
||||
|
||||
if extra_flags is not None:
|
||||
cmd = '{0} {1}'.format(cmd, extra_flags)
|
||||
cmd.extend(shlex.split(extra_flags))
|
||||
|
||||
# If php is set, prepend it
|
||||
if php is not None:
|
||||
cmd = php + ' ' + cmd
|
||||
cmd = [php] + cmd
|
||||
|
||||
# Add Working Dir
|
||||
if dir is not None:
|
||||
cmd += ' --working-dir=' + dir
|
||||
if directory is not None:
|
||||
cmd.extend(['--working-dir', directory])
|
||||
|
||||
# Other Settings
|
||||
if quiet is True:
|
||||
cmd += ' --quiet'
|
||||
cmd.append('--quiet')
|
||||
|
||||
if no_dev is True:
|
||||
cmd += ' --no-dev'
|
||||
cmd.append('--no-dev')
|
||||
|
||||
if prefer_source is True:
|
||||
cmd += ' --prefer-source'
|
||||
cmd.append('--prefer-source')
|
||||
|
||||
if prefer_dist is True:
|
||||
cmd += ' --prefer-dist'
|
||||
cmd.append('--prefer-dist')
|
||||
|
||||
if no_scripts is True:
|
||||
cmd += ' --no-scripts'
|
||||
cmd.append('--no-scripts')
|
||||
|
||||
if no_plugins is True:
|
||||
cmd += ' --no-plugins'
|
||||
cmd.append('--no-plugins')
|
||||
|
||||
if optimize is True:
|
||||
cmd += ' --optimize-autoloader'
|
||||
cmd.append('--optimize-autoloader')
|
||||
|
||||
result = __salt__['cmd.run_all'](cmd,
|
||||
runas=runas,
|
||||
@ -192,7 +199,7 @@ def _run_composer(action,
|
||||
return result
|
||||
|
||||
|
||||
def install(dir,
|
||||
def install(directory,
|
||||
composer=None,
|
||||
php=None,
|
||||
runas=None,
|
||||
@ -211,7 +218,7 @@ def install(dir,
|
||||
system PATH & making it executable, the ``composer`` and ``php`` parameters
|
||||
will need to be set to the location of the executables.
|
||||
|
||||
dir
|
||||
directory
|
||||
Directory location of the composer.json file.
|
||||
|
||||
composer
|
||||
@ -260,7 +267,7 @@ def install(dir,
|
||||
no_dev=True optimize=True
|
||||
'''
|
||||
result = _run_composer('install',
|
||||
dir=dir,
|
||||
directory=directory,
|
||||
composer=composer,
|
||||
php=php,
|
||||
runas=runas,
|
||||
@ -275,7 +282,7 @@ def install(dir,
|
||||
return result
|
||||
|
||||
|
||||
def update(dir,
|
||||
def update(directory,
|
||||
composer=None,
|
||||
php=None,
|
||||
runas=None,
|
||||
@ -297,7 +304,7 @@ def update(dir,
|
||||
system PATH & making it executable, the ``composer`` and ``php`` parameters
|
||||
will need to be set to the location of the executables.
|
||||
|
||||
dir
|
||||
directory
|
||||
Directory location of the composer.json file.
|
||||
|
||||
composer
|
||||
@ -346,8 +353,8 @@ def update(dir,
|
||||
no_dev=True optimize=True
|
||||
'''
|
||||
result = _run_composer('update',
|
||||
directory=directory,
|
||||
extra_flags='--no-progress',
|
||||
dir=dir,
|
||||
composer=composer,
|
||||
php=php,
|
||||
runas=runas,
|
||||
|
@ -365,7 +365,7 @@ def cache_file(path, saltenv='base', env=None):
|
||||
result = __context__['cp.fileclient'].cache_file(path, saltenv)
|
||||
if not result:
|
||||
log.error(
|
||||
'Unable to cache file {0!r} from saltenv {1!r}.'.format(
|
||||
'Unable to cache file \'{0}\' from saltenv \'{1}\'.'.format(
|
||||
path, saltenv
|
||||
)
|
||||
)
|
||||
@ -685,7 +685,7 @@ def push(path, keep_symlinks=False, upload_path=None):
|
||||
salt '*' cp.push /etc/system-release keep_symlinks=True
|
||||
salt '*' cp.push /etc/fstab upload_path='/new/path/fstab'
|
||||
'''
|
||||
log.debug('Trying to copy {0!r} to master'.format(path))
|
||||
log.debug('Trying to copy \'{0}\' to master'.format(path))
|
||||
if '../' in path or not os.path.isabs(path):
|
||||
log.debug('Path must be absolute, returning False')
|
||||
return False
|
||||
|
@ -12,12 +12,15 @@ import os.path
|
||||
# Import 3rd-party libs
|
||||
from salt.ext.six.moves import urllib # pylint: disable=import-error
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.itertools
|
||||
|
||||
# Don't shadow built-in's.
|
||||
__func_alias__ = {
|
||||
'list_': 'list'
|
||||
}
|
||||
|
||||
PKGUTIL = "/usr/sbin/pkgutil"
|
||||
__PKGUTIL = '/usr/sbin/pkgutil'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
@ -36,8 +39,8 @@ def list_():
|
||||
|
||||
salt '*' darwin_pkgutil.list
|
||||
'''
|
||||
cmd = PKGUTIL + ' --pkgs'
|
||||
return __salt__['cmd.run_stdout'](cmd)
|
||||
cmd = [__PKGUTIL, '--pkgs']
|
||||
return __salt__['cmd.run_stdout'](cmd, python_shell=False)
|
||||
|
||||
|
||||
def is_installed(package_id):
|
||||
@ -50,20 +53,15 @@ def is_installed(package_id):
|
||||
|
||||
salt '*' darwin_pkgutil.is_installed com.apple.pkg.gcc4.2Leo
|
||||
'''
|
||||
def has_package_id(lines):
|
||||
for line in lines:
|
||||
for line in salt.utils.itertools.split(list_(), '\n'):
|
||||
if line == package_id:
|
||||
return True
|
||||
return False
|
||||
|
||||
cmd = PKGUTIL + ' --pkgs'
|
||||
out = __salt__['cmd.run_stdout'](cmd)
|
||||
return has_package_id(out.splitlines())
|
||||
|
||||
|
||||
def _install_from_path(path):
|
||||
if not os.path.exists(path):
|
||||
msg = "Path {0!r} does not exist, cannot install".format(path)
|
||||
msg = 'Path \'{0}\' does not exist, cannot install'.format(path)
|
||||
raise ValueError(msg)
|
||||
else:
|
||||
cmd = 'installer -pkg "{0}" -target /'.format(path)
|
||||
@ -78,8 +76,7 @@ def install(source, package_id=None):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' darwin_pkgutil.install source=/vagrant/build_essentials.pkg \
|
||||
package_id=com.apple.pkg.gcc4.2Leo
|
||||
salt '*' darwin_pkgutil.install source=/vagrant/build_essentials.pkg package_id=com.apple.pkg.gcc4.2Leo
|
||||
'''
|
||||
if package_id is not None and is_installed(package_id):
|
||||
return ''
|
||||
@ -88,5 +85,5 @@ def install(source, package_id=None):
|
||||
if uri.scheme == "":
|
||||
return _install_from_path(source)
|
||||
else:
|
||||
msg = "Unsupported scheme for source uri: {0!r}".format(uri.scheme)
|
||||
msg = 'Unsupported scheme for source uri: \'{0}\''.format(uri.scheme)
|
||||
raise ValueError(msg)
|
||||
|
@ -360,9 +360,9 @@ def __within2(value, within=None, errmsg=None, dtype=None):
|
||||
typename = getattr(dtype, '__name__',
|
||||
hasattr(dtype, '__class__')
|
||||
and getattr(dtype.__class__, 'name', dtype))
|
||||
errmsg = '{0} within {1!r}'.format(typename, within)
|
||||
errmsg = '{0} within \'{1}\''.format(typename, within)
|
||||
else:
|
||||
errmsg = 'within {0!r}'.format(within)
|
||||
errmsg = 'within \'{0}\''.format(within)
|
||||
return (valid, _value, errmsg)
|
||||
|
||||
|
||||
@ -1259,7 +1259,11 @@ def _parse_settings_eth(opts, iface_type, enabled, iface):
|
||||
_optname, valuestr, addrfam=addrfam)
|
||||
|
||||
if not valid:
|
||||
_raise_error_iface(iface, '{0!r} {1!r}'.format(opt, valuestr), [errmsg]) # TODO
|
||||
_raise_error_iface(
|
||||
iface,
|
||||
'\'{0}\' \'{1}\''.format(opt, valuestr),
|
||||
[errmsg]
|
||||
)
|
||||
|
||||
# replace dashes with underscores for jinja
|
||||
_optname = _optname.replace('-', '_')
|
||||
@ -1543,14 +1547,10 @@ def build_bond(iface, **settings):
|
||||
_write_file(iface, data, _DEB_NETWORK_CONF_FILES, '{0}.conf'.format(iface))
|
||||
path = os.path.join(_DEB_NETWORK_CONF_FILES, '{0}.conf'.format(iface))
|
||||
if deb_major == '5':
|
||||
__salt__['cmd.run'](
|
||||
'sed -i -e "/^alias\\s{0}.*/d" /etc/modprobe.conf'.format(iface),
|
||||
python_shell=False
|
||||
)
|
||||
__salt__['cmd.run'](
|
||||
'sed -i -e "/^options\\s{0}.*/d" /etc/modprobe.conf'.format(iface),
|
||||
python_shell=False
|
||||
)
|
||||
for line_type in ('alias', 'options'):
|
||||
cmd = ['sed', '-i', '-e', r'/^{0}\s{1}.*/d'.format(line_type, iface),
|
||||
'/etc/modprobe.conf']
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
__salt__['file.append']('/etc/modprobe.conf', path)
|
||||
|
||||
# Load kernel module
|
||||
@ -1606,7 +1606,10 @@ def build_interface(iface, iface_type, enabled, **settings):
|
||||
|
||||
elif iface_type == 'bridge':
|
||||
if 'ports' not in settings:
|
||||
msg = 'ports is a required setting for bridge interfaces on Debian or Ubuntu based systems'
|
||||
msg = (
|
||||
'ports is a required setting for bridge interfaces on Debian '
|
||||
'or Ubuntu based systems'
|
||||
)
|
||||
log.error(msg)
|
||||
raise AttributeError(msg)
|
||||
__salt__['pkg.install']('bridge-utils')
|
||||
@ -1648,17 +1651,27 @@ def build_routes(iface, **settings):
|
||||
log.error('Could not load template route_eth.jinja')
|
||||
return ''
|
||||
|
||||
add_routecfg = template.render(route_type='add', routes=opts['routes'], iface=iface)
|
||||
add_routecfg = template.render(route_type='add',
|
||||
routes=opts['routes'],
|
||||
iface=iface)
|
||||
|
||||
del_routecfg = template.render(route_type='del', routes=opts['routes'], iface=iface)
|
||||
del_routecfg = template.render(route_type='del',
|
||||
routes=opts['routes'],
|
||||
iface=iface)
|
||||
|
||||
if 'test' in settings and settings['test']:
|
||||
return _read_temp(add_routecfg + del_routecfg)
|
||||
|
||||
filename = _write_file_routes(iface, add_routecfg, _DEB_NETWORK_UP_DIR, 'route-{0}')
|
||||
filename = _write_file_routes(iface,
|
||||
add_routecfg,
|
||||
_DEB_NETWORK_UP_DIR,
|
||||
'route-{0}')
|
||||
results = _read_file(filename)
|
||||
|
||||
filename = _write_file_routes(iface, del_routecfg, _DEB_NETWORK_DOWN_DIR, 'route-{0}')
|
||||
filename = _write_file_routes(iface,
|
||||
del_routecfg,
|
||||
_DEB_NETWORK_DOWN_DIR,
|
||||
'route-{0}')
|
||||
results += _read_file(filename)
|
||||
|
||||
return results
|
||||
@ -1677,7 +1690,7 @@ def down(iface, iface_type):
|
||||
# Slave devices are controlled by the master.
|
||||
# Source 'interfaces' aren't brought down.
|
||||
if iface_type not in ['slave', 'source']:
|
||||
return __salt__['cmd.run']('ifdown {0}'.format(iface))
|
||||
return __salt__['cmd.run'](['ifdown', iface])
|
||||
return None
|
||||
|
||||
|
||||
@ -1737,8 +1750,8 @@ def up(iface, iface_type): # pylint: disable=C0103
|
||||
'''
|
||||
# Slave devices are controlled by the master.
|
||||
# Source 'interfaces' aren't brought up.
|
||||
if iface_type not in ['slave', 'source']:
|
||||
return __salt__['cmd.run']('ifup {0}'.format(iface))
|
||||
if iface_type not in ('slave', 'source'):
|
||||
return __salt__['cmd.run'](['ifup', iface])
|
||||
return None
|
||||
|
||||
|
||||
|
@ -205,7 +205,7 @@ def SPF(domain, record='SPF', nameserver=None):
|
||||
# In this case, 0 is not the same as False
|
||||
if result['retcode'] != 0:
|
||||
log.warn(
|
||||
'dig returned exit code {0!r}. Returning empty list as fallback.'
|
||||
'dig returned exit code \'{0}\'. Returning empty list as fallback.'
|
||||
.format(result['retcode'])
|
||||
)
|
||||
return []
|
||||
|
@ -331,7 +331,7 @@ def _get_image_infos(image):
|
||||
if not status['id']:
|
||||
_invalid(status)
|
||||
raise CommandExecutionError(
|
||||
'ImageID {0!r} could not be resolved to '
|
||||
'ImageID \'{0}\' could not be resolved to '
|
||||
'an existing Image'.format(image)
|
||||
)
|
||||
return status['out']
|
||||
@ -859,8 +859,8 @@ def kill(container, signal=None):
|
||||
# no need to check if container is running
|
||||
# because some signals might not stop the container.
|
||||
_valid(status,
|
||||
comment='Kill signal {0!r} successfully'
|
||||
' sent to the container {1!r}'.format(signal, container),
|
||||
comment='Kill signal \'{0}\' successfully'
|
||||
' sent to the container \'{1}\''.format(signal, container),
|
||||
id_=container)
|
||||
else:
|
||||
if not is_running(dcontainer):
|
||||
@ -1858,7 +1858,7 @@ def _run_wrapper(status, container, func, cmd, *args, **kwargs):
|
||||
)
|
||||
else:
|
||||
raise NotImplementedError(
|
||||
'Unknown docker ExecutionDriver {0!r}. Or didn\'t find command'
|
||||
'Unknown docker ExecutionDriver \'{0}\'. Or didn\'t find command'
|
||||
' to attach to the container'.format(driver))
|
||||
|
||||
# now execute the command
|
||||
|
@ -154,7 +154,7 @@ def check_db(*names, **kwargs):
|
||||
ret = {}
|
||||
for name in names:
|
||||
if name in ret:
|
||||
log.warning('pkg.check_db: Duplicate package name {0!r} '
|
||||
log.warning('pkg.check_db: Duplicate package name \'{0}\' '
|
||||
'submitted'.format(name))
|
||||
continue
|
||||
if '/' not in name:
|
||||
@ -587,16 +587,16 @@ def install(name=None,
|
||||
if pkg_params is None or len(pkg_params) == 0:
|
||||
return {}
|
||||
elif pkg_type == 'file':
|
||||
emerge_opts = 'tbz2file'
|
||||
emerge_opts = ['tbz2file']
|
||||
else:
|
||||
emerge_opts = ''
|
||||
emerge_opts = []
|
||||
|
||||
if binhost == 'try':
|
||||
bin_opts = '-g'
|
||||
bin_opts = ['-g']
|
||||
elif binhost == 'force':
|
||||
bin_opts = '-G'
|
||||
bin_opts = ['-G']
|
||||
else:
|
||||
bin_opts = ''
|
||||
bin_opts = []
|
||||
|
||||
changes = {}
|
||||
|
||||
@ -655,7 +655,10 @@ def install(name=None,
|
||||
targets.append(target)
|
||||
else:
|
||||
targets = pkg_params
|
||||
cmd = 'emerge --ask n --quiet {0} {1} {2}'.format(bin_opts, emerge_opts, ' '.join(targets))
|
||||
cmd = ['emerge', '--ask', 'n', '--quiet']
|
||||
cmd.extend(bin_opts)
|
||||
cmd.extend(emerge_opts)
|
||||
cmd.extend(targets)
|
||||
|
||||
old = list_pkgs()
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
@ -708,14 +711,17 @@ def update(pkg, slot=None, fromrepo=None, refresh=False, binhost=None):
|
||||
full_atom = '{0}::{1}'.format(full_atom, fromrepo)
|
||||
|
||||
if binhost == 'try':
|
||||
bin_opts = '-g'
|
||||
bin_opts = ['-g']
|
||||
elif binhost == 'force':
|
||||
bin_opts = '-G'
|
||||
bin_opts = ['-G']
|
||||
else:
|
||||
bin_opts = ''
|
||||
bin_opts = []
|
||||
|
||||
old = list_pkgs()
|
||||
cmd = 'emerge --ask n --quiet --update --newuse --oneshot {0} {1}'.format(bin_opts, full_atom)
|
||||
cmd = ['emerge', '--ask', 'n', '--quiet', '--update', '--newuse',
|
||||
'--oneshot']
|
||||
cmd.extend(bin_opts)
|
||||
cmd.append(full_atom)
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
@ -755,18 +761,17 @@ def upgrade(refresh=True, binhost=None, backtrack=3):
|
||||
'''
|
||||
ret = {'changes': {},
|
||||
'result': True,
|
||||
'comment': '',
|
||||
}
|
||||
'comment': ''}
|
||||
|
||||
if salt.utils.is_true(refresh):
|
||||
refresh_db()
|
||||
|
||||
if binhost == 'try':
|
||||
bin_opts = '--getbinpkg'
|
||||
bin_opts = ['--getbinpkg']
|
||||
elif binhost == 'force':
|
||||
bin_opts = '--getbinpkgonly'
|
||||
bin_opts = ['--getbinpkgonly']
|
||||
else:
|
||||
bin_opts = ''
|
||||
bin_opts = []
|
||||
|
||||
old = list_pkgs()
|
||||
cmd = ['emerge',
|
||||
@ -777,7 +782,7 @@ def upgrade(refresh=True, binhost=None, backtrack=3):
|
||||
'--newuse',
|
||||
'--deep']
|
||||
if bin_opts:
|
||||
cmd.append(bin_opts)
|
||||
cmd.extend(bin_opts)
|
||||
cmd.append('@world')
|
||||
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
@ -846,8 +851,8 @@ def remove(name=None, slot=None, fromrepo=None, pkgs=None, **kwargs):
|
||||
|
||||
if not targets:
|
||||
return {}
|
||||
cmd = 'emerge --ask n --quiet --unmerge --quiet-unmerge-warn ' \
|
||||
'{0}'.format(' '.join(targets))
|
||||
cmd = ['emerge', '--ask', 'n', '--quiet', '--unmerge',
|
||||
'--quiet-unmerge-warn'] + targets
|
||||
__salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
@ -938,7 +943,7 @@ def depclean(name=None, slot=None, fromrepo=None, pkgs=None):
|
||||
else:
|
||||
targets = [x for x in pkg_params if x in old]
|
||||
|
||||
cmd = 'emerge --ask n --quiet --depclean {0}'.format(' '.join(targets))
|
||||
cmd = ['emerge', '--ask', 'n', '--quiet', '--depclean'] + targets
|
||||
__salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
@ -71,7 +71,7 @@ def setval(key, val, false_unsets=False, permanent=False):
|
||||
|
||||
if not isinstance(key, six.string_types):
|
||||
log.debug(
|
||||
'{0}: "key" argument is not a string type: {1!r}'
|
||||
'{0}: \'key\' argument is not a string type: \'{1}\''
|
||||
.format(__name__, key)
|
||||
)
|
||||
if val is False:
|
||||
@ -84,7 +84,7 @@ def setval(key, val, false_unsets=False, permanent=False):
|
||||
except Exception as exc:
|
||||
log.error(
|
||||
'{0}: Exception occurred when unsetting '
|
||||
'environ key "{1!r}": {2!r}'
|
||||
'environ key \'{1}\': \'{2}\''
|
||||
.format(__name__, key, exc)
|
||||
)
|
||||
return False
|
||||
@ -99,14 +99,14 @@ def setval(key, val, false_unsets=False, permanent=False):
|
||||
except Exception as exc:
|
||||
log.error(
|
||||
'{0}: Exception occurred when setting'
|
||||
'environ key "{1!r}": {2!r}'
|
||||
'environ key \'{1}\': \'{2}\''
|
||||
.format(__name__, key, exc)
|
||||
)
|
||||
return False
|
||||
else:
|
||||
log.debug(
|
||||
'{0}: "val" argument for key "{1!r}" is not a string '
|
||||
'or False: {2!r}'
|
||||
'{0}: \'val\' argument for key \'{1}\' is not a string '
|
||||
'or False: \'{2}\''
|
||||
.format(__name__, key, val)
|
||||
)
|
||||
return False
|
||||
@ -162,7 +162,7 @@ def setenv(environ, false_unsets=False, clear_all=False, update_minion=False, pe
|
||||
ret = {}
|
||||
if not isinstance(environ, dict):
|
||||
log.debug(
|
||||
'{0}: "environ" argument is not a dict: {1!r}'
|
||||
'{0}: \'environ\' argument is not a dict: \'{1}\''
|
||||
.format(__name__, environ)
|
||||
)
|
||||
return False
|
||||
@ -178,8 +178,8 @@ def setenv(environ, false_unsets=False, clear_all=False, update_minion=False, pe
|
||||
ret[key] = setval(key, val, false_unsets, permanent=permanent)
|
||||
else:
|
||||
log.debug(
|
||||
'{0}: "val" argument for key "{1!r}" is not a string '
|
||||
'or False: {2!r}'
|
||||
'{0}: \'val\' argument for key \'{1}\' is not a string '
|
||||
'or False: \'{2}\''
|
||||
.format(__name__, key, val)
|
||||
)
|
||||
return False
|
||||
@ -215,7 +215,7 @@ def get(key, default=''):
|
||||
'''
|
||||
if not isinstance(key, six.string_types):
|
||||
log.debug(
|
||||
'{0}: "key" argument is not a string type: {1!r}'
|
||||
'{0}: \'key\' argument is not a string type: \'{1}\''
|
||||
.format(__name__, key)
|
||||
)
|
||||
return False
|
||||
@ -243,7 +243,7 @@ def has_value(key, value=None):
|
||||
'''
|
||||
if not isinstance(key, six.string_types):
|
||||
log.debug(
|
||||
'{0}: "key" argument is not a string type: {1!r}'
|
||||
'{0}: \'key\' argument is not a string type: \'{1}\''
|
||||
.format(__name__, key)
|
||||
)
|
||||
return False
|
||||
@ -287,7 +287,7 @@ def item(keys, default=''):
|
||||
key_list = keys
|
||||
else:
|
||||
log.debug(
|
||||
'{0}: "keys" argument is not a string or list type: {1!r}'
|
||||
'{0}: \'keys\' argument is not a string or list type: \'{1}\''
|
||||
.format(__name__, keys)
|
||||
)
|
||||
for key in key_list:
|
||||
|
@ -22,6 +22,7 @@ import logging
|
||||
import operator
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import stat
|
||||
import sys
|
||||
@ -561,7 +562,7 @@ def check_hash(path, file_hash):
|
||||
# Support "=" for backward compatibility.
|
||||
hash_parts = file_hash.split('=', 1)
|
||||
if len(hash_parts) != 2:
|
||||
raise ValueError('Bad hash format: {0!r}'.format(file_hash))
|
||||
raise ValueError('Bad hash format: \'{0}\''.format(file_hash))
|
||||
hash_form, hash_value = hash_parts
|
||||
return get_hash(path, hash_form) == hash_value
|
||||
|
||||
@ -776,19 +777,19 @@ def sed(path,
|
||||
if sys.platform == 'darwin':
|
||||
options = options.replace('-r', '-E')
|
||||
|
||||
cmd = (
|
||||
r'''sed {backup}{options} '{limit}{negate_match}s/{before}/{after}/{flags}' {path}'''
|
||||
.format(
|
||||
backup='-i{0} '.format(backup) if backup else '-i ',
|
||||
options=options,
|
||||
cmd = ['sed']
|
||||
cmd.append('-i{0}'.format(backup) if backup else '-i')
|
||||
cmd.extend(shlex.split(options))
|
||||
cmd.append(
|
||||
r'{limit}{negate_match}s/{before}/{after}/{flags}'.format(
|
||||
limit='/{0}/ '.format(limit) if limit else '',
|
||||
negate_match='!' if negate_match else '',
|
||||
before=before,
|
||||
after=after,
|
||||
flags=flags,
|
||||
path=path,
|
||||
negate_match='!' if negate_match else '',
|
||||
flags=flags
|
||||
)
|
||||
)
|
||||
cmd.append(path)
|
||||
|
||||
return __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
@ -824,12 +825,16 @@ def sed_contains(path,
|
||||
if sys.platform == 'darwin':
|
||||
options = options.replace('-r', '-E')
|
||||
|
||||
cmd = r"sed {options} '{limit}s/{before}/$/{flags}' {path}".format(
|
||||
options=options,
|
||||
cmd = ['sed']
|
||||
cmd.extend(shlex.split(options))
|
||||
cmd.append(
|
||||
r'{limit}s/{before}/$/{flags}'.format(
|
||||
limit='/{0}/ '.format(limit) if limit else '',
|
||||
before=before,
|
||||
flags='p{0}'.format(flags),
|
||||
path=path)
|
||||
flags='p{0}'.format(flags)
|
||||
)
|
||||
)
|
||||
cmd.append(path)
|
||||
|
||||
result = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
|
||||
@ -2241,20 +2246,22 @@ def patch(originalfile, patchfile, options='', dry_run=False):
|
||||
|
||||
salt '*' file.patch /opt/file.txt /tmp/file.txt.patch
|
||||
'''
|
||||
if dry_run:
|
||||
if __grains__['kernel'] in ('FreeBSD', 'OpenBSD'):
|
||||
dry_run_opt = ' -C'
|
||||
else:
|
||||
dry_run_opt = ' --dry-run'
|
||||
else:
|
||||
dry_run_opt = ''
|
||||
|
||||
patchpath = salt.utils.which('patch')
|
||||
if not patchpath:
|
||||
raise CommandExecutionError('patch executable not found. Is the distribution\'s patch package installed?')
|
||||
raise CommandExecutionError(
|
||||
'patch executable not found. Is the distribution\'s patch '
|
||||
'package installed?'
|
||||
)
|
||||
|
||||
cmd = [patchpath]
|
||||
cmd.extend(shlex.split(options))
|
||||
if dry_run:
|
||||
if __grains__['kernel'] in ('FreeBSD', 'OpenBSD'):
|
||||
cmd.append('-C')
|
||||
else:
|
||||
cmd.append('--dry-run')
|
||||
cmd.extend([originalfile, patchfile])
|
||||
|
||||
cmd = '{0} {1}{2} "{3}" "{4}"'.format(
|
||||
patchpath, options, dry_run_opt, originalfile, patchfile)
|
||||
return __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
|
||||
@ -2702,7 +2709,7 @@ def link(src, path):
|
||||
os.link(src, path)
|
||||
return True
|
||||
except (OSError, IOError):
|
||||
raise CommandExecutionError('Could not create {0!r}'.format(path))
|
||||
raise CommandExecutionError('Could not create \'{0}\''.format(path))
|
||||
return False
|
||||
|
||||
|
||||
@ -2743,7 +2750,7 @@ def symlink(src, path):
|
||||
os.symlink(src, path)
|
||||
return True
|
||||
except (OSError, IOError):
|
||||
raise CommandExecutionError('Could not create {0!r}'.format(path))
|
||||
raise CommandExecutionError('Could not create \'{0}\''.format(path))
|
||||
return False
|
||||
|
||||
|
||||
@ -2768,7 +2775,7 @@ def rename(src, dst):
|
||||
return True
|
||||
except OSError:
|
||||
raise CommandExecutionError(
|
||||
'Could not rename {0!r} to {1!r}'.format(src, dst)
|
||||
'Could not rename \'{0}\' to \'{1}\''.format(src, dst)
|
||||
)
|
||||
return False
|
||||
|
||||
@ -2819,7 +2826,7 @@ def copy(src, dst, recurse=False, remove_existing=False):
|
||||
shutil.copyfile(src, dst)
|
||||
except OSError:
|
||||
raise CommandExecutionError(
|
||||
'Could not copy {0!r} to {1!r}'.format(src, dst)
|
||||
'Could not copy \'{0}\' to \'{1}\''.format(src, dst)
|
||||
)
|
||||
|
||||
if not salt.utils.is_windows():
|
||||
@ -2967,7 +2974,7 @@ def statvfs(path):
|
||||
'f_blocks', 'f_bsize', 'f_favail', 'f_ffree', 'f_files', 'f_flag',
|
||||
'f_frsize', 'f_namemax'))
|
||||
except (OSError, IOError):
|
||||
raise CommandExecutionError('Could not statvfs {0!r}'.format(path))
|
||||
raise CommandExecutionError('Could not statvfs \'{0}\''.format(path))
|
||||
return False
|
||||
|
||||
|
||||
@ -3079,7 +3086,7 @@ def remove(path):
|
||||
return True
|
||||
except (OSError, IOError) as exc:
|
||||
raise CommandExecutionError(
|
||||
'Could not remove {0!r}: {1}'.format(path, exc)
|
||||
'Could not remove \'{0}\': {1}'.format(path, exc)
|
||||
)
|
||||
return False
|
||||
|
||||
@ -3141,9 +3148,9 @@ def restorecon(path, recursive=False):
|
||||
salt '*' file.restorecon /home/user/.ssh/authorized_keys
|
||||
'''
|
||||
if recursive:
|
||||
cmd = 'restorecon -FR {0}'.format(path)
|
||||
cmd = ['restorecon', '-FR', path]
|
||||
else:
|
||||
cmd = 'restorecon -F {0}'.format(path)
|
||||
cmd = ['restorecon', '-F', path]
|
||||
return not __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
|
||||
|
||||
@ -3157,12 +3164,14 @@ def get_selinux_context(path):
|
||||
|
||||
salt '*' file.get_selinux_context /etc/hosts
|
||||
'''
|
||||
out = __salt__['cmd.run']('ls -Z {0}'.format(path), python_shell=False)
|
||||
out = __salt__['cmd.run'](['ls', '-Z', path], python_shell=False)
|
||||
|
||||
try:
|
||||
ret = re.search(r'\w+:\w+:\w+:\w+', out).group(0)
|
||||
except AttributeError:
|
||||
ret = 'No selinux context information is available for {0}'.format(path)
|
||||
ret = (
|
||||
'No selinux context information is available for {0}'.format(path)
|
||||
)
|
||||
|
||||
return ret
|
||||
|
||||
@ -3184,17 +3193,17 @@ def set_selinux_context(path,
|
||||
if not any((user, role, type, range)):
|
||||
return False
|
||||
|
||||
cmd = 'chcon '
|
||||
cmd = ['chcon']
|
||||
if user:
|
||||
cmd += '-u {0} '.format(user)
|
||||
cmd.extend(['-u', user])
|
||||
if role:
|
||||
cmd += '-r {0} '.format(role)
|
||||
cmd.extend(['-r', role])
|
||||
if type:
|
||||
cmd += '-t {0} '.format(type)
|
||||
cmd.extend(['-t', type])
|
||||
if range:
|
||||
cmd += '-l {0} '.format(range)
|
||||
cmd.extend(['-l', range])
|
||||
cmd.append(path)
|
||||
|
||||
cmd += path
|
||||
ret = not __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
if ret:
|
||||
return get_selinux_context(path)
|
||||
@ -3379,7 +3388,7 @@ def get_managed(
|
||||
# exists doesn't play nice with sfn as bool
|
||||
# but if cache failed, sfn == False
|
||||
if not sfn or not os.path.exists(sfn):
|
||||
return sfn, {}, 'Source file {0!r} not found'.format(source)
|
||||
return sfn, {}, 'Source file \'{0}\' not found'.format(source)
|
||||
if sfn == name:
|
||||
raise SaltInvocationError(
|
||||
'Source file cannot be the same as destination'
|
||||
@ -3984,7 +3993,7 @@ def manage_file(name,
|
||||
sfn = __salt__['cp.cache_file'](source, saltenv)
|
||||
if not sfn:
|
||||
return _error(
|
||||
ret, 'Source file {0!r} not found'.format(source))
|
||||
ret, 'Source file \'{0}\' not found'.format(source))
|
||||
# If the downloaded file came from a non salt server or local source
|
||||
# verify that it matches the intended sum value
|
||||
if _urlparse(source).scheme not in ('salt', ''):
|
||||
@ -4077,7 +4086,7 @@ def manage_file(name,
|
||||
sfn = __salt__['cp.cache_file'](source, saltenv)
|
||||
if not sfn:
|
||||
return _error(
|
||||
ret, 'Source file {0!r} not found'.format(source))
|
||||
ret, 'Source file \'{0}\' not found'.format(source))
|
||||
# If the downloaded file came from a non salt server source verify
|
||||
# that it matches the intended sum value
|
||||
if _urlparse(source).scheme != 'salt':
|
||||
@ -4146,7 +4155,7 @@ def manage_file(name,
|
||||
sfn = __salt__['cp.cache_file'](source, saltenv)
|
||||
if not sfn:
|
||||
return _error(
|
||||
ret, 'Source file {0!r} not found'.format(source))
|
||||
ret, 'Source file \'{0}\' not found'.format(source))
|
||||
# If the downloaded file came from a non salt server source verify
|
||||
# that it matches the intended sum value
|
||||
if _urlparse(source).scheme != 'salt':
|
||||
@ -4300,12 +4309,12 @@ def makedirs_(path,
|
||||
|
||||
if os.path.isdir(dirname):
|
||||
# There's nothing for us to do
|
||||
msg = 'Directory {0!r} already exists'.format(dirname)
|
||||
msg = 'Directory \'{0}\' already exists'.format(dirname)
|
||||
log.debug(msg)
|
||||
return msg
|
||||
|
||||
if os.path.exists(dirname):
|
||||
msg = 'The path {0!r} already exists and is not a directory'.format(
|
||||
msg = 'The path \'{0}\' already exists and is not a directory'.format(
|
||||
dirname
|
||||
)
|
||||
log.debug(msg)
|
||||
@ -4635,7 +4644,7 @@ def mknod(name,
|
||||
ret = mknod_fifo(name, user, group, mode)
|
||||
else:
|
||||
raise SaltInvocationError(
|
||||
'Node type unavailable: {0!r}. Available node types are '
|
||||
'Node type unavailable: \'{0}\'. Available node types are '
|
||||
'character (\'c\'), block (\'b\'), and pipe (\'p\').'.format(ntype)
|
||||
)
|
||||
return ret
|
||||
@ -4888,7 +4897,7 @@ remove_backup = delete_backup
|
||||
|
||||
def grep(path,
|
||||
pattern,
|
||||
*args):
|
||||
*opts):
|
||||
'''
|
||||
Grep for a string in the specified file
|
||||
|
||||
@ -4897,40 +4906,52 @@ def grep(path,
|
||||
versions of Salt
|
||||
|
||||
path
|
||||
A file path
|
||||
Path to the file to be searched
|
||||
|
||||
.. note::
|
||||
Globbing is supported (i.e. ``/var/log/foo/*.log``, but if globbing
|
||||
is being used then the path should be quoted to keep the shell from
|
||||
attempting to expand the glob expression.
|
||||
|
||||
pattern
|
||||
A string. For example:
|
||||
``test``
|
||||
``a[0-5]``
|
||||
args
|
||||
grep options. For example:
|
||||
``" -v"``
|
||||
``" -i -B2"``
|
||||
Pattern to match. For example: ``test``, or ``a[0-5]``
|
||||
|
||||
opts
|
||||
Additional command-line flags to pass to the grep command. For example:
|
||||
``-v``, or ``-i -B2``
|
||||
|
||||
.. note::
|
||||
The options should come after a double-dash (as shown in the
|
||||
examples below) to keep Salt's own argument parser from
|
||||
interpreting them.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' file.grep /etc/passwd nobody
|
||||
salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr " -i"
|
||||
salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr " -i -B2"
|
||||
salt '*' file.grep "/etc/sysconfig/network-scripts/*" ipaddr " -i -l"
|
||||
salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr -- -i
|
||||
salt '*' file.grep /etc/sysconfig/network-scripts/ifcfg-eth0 ipaddr -- -i -B2
|
||||
salt '*' file.grep "/etc/sysconfig/network-scripts/*" ipaddr -- -i -l
|
||||
'''
|
||||
path = os.path.expanduser(path)
|
||||
|
||||
if args:
|
||||
options = ' '.join(args)
|
||||
else:
|
||||
options = ''
|
||||
cmd = (
|
||||
r'''grep {options} {pattern} {path}'''
|
||||
.format(
|
||||
options=options,
|
||||
pattern=pattern,
|
||||
path=path,
|
||||
)
|
||||
split_opts = []
|
||||
for opt in opts:
|
||||
try:
|
||||
opt = shlex.split(opt)
|
||||
except AttributeError:
|
||||
opt = shlex.split(str(opt))
|
||||
if len(opt) > 1:
|
||||
salt.utils.warn_until(
|
||||
'Carbon',
|
||||
'Additional command line options for file.grep should be '
|
||||
'passed one at a time, please do not pass more than one in a '
|
||||
'single argument.'
|
||||
)
|
||||
split_opts.extend(opt)
|
||||
|
||||
cmd = ['grep'] + split_opts + [pattern, path]
|
||||
try:
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
except (IOError, OSError) as exc:
|
||||
|
@ -139,7 +139,9 @@ def _match(names):
|
||||
|
||||
# Look for full matches
|
||||
full_pkg_strings = []
|
||||
out = __salt__['cmd.run_stdout']('pkg_info', output_loglevel='trace')
|
||||
out = __salt__['cmd.run_stdout'](['pkg_info'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
for line in out.splitlines():
|
||||
try:
|
||||
full_pkg_strings.append(line.split()[0])
|
||||
@ -158,7 +160,7 @@ def _match(names):
|
||||
else:
|
||||
ambiguous.append(name)
|
||||
errors.append(
|
||||
'Ambiguous package {0!r}. Full name/version required. '
|
||||
'Ambiguous package \'{0}\'. Full name/version required. '
|
||||
'Possible matches: {1}'.format(
|
||||
name,
|
||||
', '.join(['{0}-{1}'.format(name, x) for x in cver])
|
||||
@ -169,7 +171,7 @@ def _match(names):
|
||||
not_matched = \
|
||||
set(names) - set(matches) - set(full_matches) - set(ambiguous)
|
||||
for name in not_matched:
|
||||
errors.append('Package {0!r} not found'.format(name))
|
||||
errors.append('Package \'{0}\' not found'.format(name))
|
||||
|
||||
return matches + full_matches, errors
|
||||
|
||||
@ -279,7 +281,9 @@ def list_pkgs(versions_as_list=False, with_origin=False, **kwargs):
|
||||
|
||||
ret = {}
|
||||
origins = {}
|
||||
out = __salt__['cmd.run_stdout']('pkg_info -ao', output_loglevel='trace')
|
||||
out = __salt__['cmd.run_stdout'](['pkg_info', '-ao'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
pkgs_re = re.compile(r'Information for ([^:]+):\s*Origin:\n([^\n]+)')
|
||||
for pkg, origin in pkgs_re.findall(out):
|
||||
if not pkg:
|
||||
@ -386,9 +390,10 @@ def install(name=None,
|
||||
|
||||
old = list_pkgs()
|
||||
__salt__['cmd.run'](
|
||||
'pkg_add {0}'.format(' '.join(args)),
|
||||
['pkg_add'] + args,
|
||||
env=env,
|
||||
output_loglevel='trace'
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
@ -448,8 +453,11 @@ def remove(name=None, pkgs=None, **kwargs):
|
||||
log.error(error)
|
||||
if not targets:
|
||||
return {}
|
||||
cmd = 'pkg_delete {0}'.format(' '.join(targets))
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
__salt__['cmd.run'](
|
||||
['pkg_delete'] + targets,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -467,7 +475,9 @@ def _rehash():
|
||||
'''
|
||||
shell = __salt__['environ.get']('SHELL', output_loglevel='trace')
|
||||
if shell.split('/')[-1] in ('csh', 'tcsh'):
|
||||
__salt__['cmd.run']('rehash', output_loglevel='trace')
|
||||
__salt__['cmd.run'](['rehash'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
||||
|
||||
def file_list(*packages):
|
||||
@ -511,13 +521,13 @@ def file_dict(*packages):
|
||||
|
||||
if packages:
|
||||
match_pattern = '\'{0}-[0-9]*\''
|
||||
matches = [match_pattern.format(p) for p in packages]
|
||||
|
||||
cmd = 'pkg_info -QL {0}'.format(' '.join(matches))
|
||||
cmd = ['pkg_info', '-QL'] + [match_pattern.format(p) for p in packages]
|
||||
else:
|
||||
cmd = 'pkg_info -QLa'
|
||||
cmd = ['pkg_info', '-QLa']
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
ret = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
||||
for line in ret['stderr'].splitlines():
|
||||
errors.append(line)
|
||||
|
@ -42,10 +42,10 @@ def _portsnap():
|
||||
'''
|
||||
Return 'portsnap --interactive' for FreeBSD 10, otherwise 'portsnap'
|
||||
'''
|
||||
return 'portsnap{0}'.format(
|
||||
' --interactive' if float(__grains__['osrelease']) >= 10
|
||||
else ''
|
||||
)
|
||||
ret = ['portsnap']
|
||||
if float(__grains__['osrelease']) >= 10:
|
||||
ret.append('--interactive')
|
||||
return ret
|
||||
|
||||
|
||||
def _check_portname(name):
|
||||
@ -55,12 +55,12 @@ def _check_portname(name):
|
||||
'''
|
||||
if not isinstance(name, string_types) or '/' not in name:
|
||||
raise SaltInvocationError(
|
||||
'Invalid port name {0!r} (category required)'.format(name)
|
||||
'Invalid port name \'{0}\' (category required)'.format(name)
|
||||
)
|
||||
|
||||
path = os.path.join('/usr/ports', name)
|
||||
if not os.path.isdir(path):
|
||||
raise SaltInvocationError('Path {0!r} does not exist'.format(path))
|
||||
raise SaltInvocationError('Path \'{0}\' does not exist'.format(path))
|
||||
|
||||
return path
|
||||
|
||||
@ -164,9 +164,15 @@ def install(name, clean=True):
|
||||
old = __salt__['pkg.list_pkgs']()
|
||||
if old.get(name.rsplit('/')[-1]):
|
||||
deinstall(name)
|
||||
cmd = ['make', 'install']
|
||||
if clean:
|
||||
cmd.append('clean')
|
||||
cmd.append('BATCH=yes')
|
||||
result = __salt__['cmd.run_all'](
|
||||
'make install{0} BATCH=yes'.format(' clean' if clean else ''),
|
||||
cwd=portpath, reset_system_locale=False
|
||||
cmd,
|
||||
cwd=portpath,
|
||||
reset_system_locale=False,
|
||||
python_shell=False
|
||||
)
|
||||
if result['retcode'] != 0:
|
||||
__context__['ports.install_error'] = result['stderr']
|
||||
@ -195,7 +201,11 @@ def deinstall(name):
|
||||
'''
|
||||
portpath = _check_portname(name)
|
||||
old = __salt__['pkg.list_pkgs']()
|
||||
__salt__['cmd.run']('make deinstall BATCH=yes', cwd=portpath)
|
||||
result = __salt__['cmd.run_all'](
|
||||
['make', 'deinstall', 'BATCH=yes'],
|
||||
cwd=portpath,
|
||||
python_shell=False
|
||||
)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = __salt__['pkg.list_pkgs']()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -215,7 +225,11 @@ def rmconfig(name):
|
||||
salt '*' ports.rmconfig security/nmap
|
||||
'''
|
||||
portpath = _check_portname(name)
|
||||
return __salt__['cmd.run']('make rmconfig', cwd=portpath)
|
||||
return __salt__['cmd.run'](
|
||||
['make', 'rmconfig'],
|
||||
cwd=portpath,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
def showconfig(name, default=False, dict_return=False):
|
||||
@ -250,7 +264,11 @@ def showconfig(name, default=False, dict_return=False):
|
||||
return default_config
|
||||
|
||||
try:
|
||||
result = __salt__['cmd.run_all']('make showconfig', cwd=portpath)
|
||||
result = __salt__['cmd.run_all'](
|
||||
['make', 'showconfig'],
|
||||
cwd=portpath,
|
||||
python_shell=False
|
||||
)
|
||||
output = result['stdout'].splitlines()
|
||||
if result['retcode'] != 0:
|
||||
error = result['stderr']
|
||||
@ -323,7 +341,7 @@ def config(name, reset=False, **kwargs):
|
||||
|
||||
if not configuration:
|
||||
raise CommandExecutionError(
|
||||
'Unable to get port configuration for {0!r}'.format(name)
|
||||
'Unable to get port configuration for \'{0}\''.format(name)
|
||||
)
|
||||
|
||||
# Get top-level key for later reference
|
||||
@ -379,7 +397,10 @@ def update(extract=False):
|
||||
|
||||
salt '*' ports.update
|
||||
'''
|
||||
result = __salt__['cmd.run_all']('{0} fetch'.format(_portsnap()))
|
||||
result = __salt__['cmd.run_all'](
|
||||
_portsnap() + ['fetch'],
|
||||
python_shell=False
|
||||
)
|
||||
if not result['retcode'] == 0:
|
||||
raise CommandExecutionError(
|
||||
'Unable to fetch ports snapshot: {0}'.format(result['stderr'])
|
||||
@ -404,13 +425,19 @@ def update(extract=False):
|
||||
ret.append('Fetched {0} new ports or files'.format(new_port_count))
|
||||
|
||||
if extract:
|
||||
result = __salt__['cmd.run_all']('{0} extract'.format(_portsnap()))
|
||||
result = __salt__['cmd.run_all'](
|
||||
_portsnap() + ['extract'],
|
||||
python_shell=False
|
||||
)
|
||||
if not result['retcode'] == 0:
|
||||
raise CommandExecutionError(
|
||||
'Unable to extract ports snapshot {0}'.format(result['stderr'])
|
||||
)
|
||||
|
||||
result = __salt__['cmd.run_all']('{0} update'.format(_portsnap()))
|
||||
result = __salt__['cmd.run_all'](
|
||||
_portsnap() + ['update'],
|
||||
python_shell=False
|
||||
)
|
||||
if not result['retcode'] == 0:
|
||||
raise CommandExecutionError(
|
||||
'Unable to apply ports snapshot: {0}'.format(result['stderr'])
|
||||
@ -466,7 +493,7 @@ def search(name):
|
||||
if '/' in name:
|
||||
if name.count('/') > 1:
|
||||
raise SaltInvocationError(
|
||||
'Invalid search string {0!r}. Port names cannot have more '
|
||||
'Invalid search string \'{0}\'. Port names cannot have more '
|
||||
'than one slash'
|
||||
)
|
||||
else:
|
||||
|
@ -4,20 +4,14 @@ Manage ruby gems.
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
|
||||
# Import python libs
|
||||
import re
|
||||
import logging
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils.itertools
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
logger = logging.getLogger(__name__) # pylint: disable=C0103
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
@ -25,6 +19,8 @@ __func_alias__ = {
|
||||
'list_': 'list'
|
||||
}
|
||||
|
||||
log = logging.getLogger(__name__) # pylint: disable=C0103
|
||||
|
||||
|
||||
def _gem(command, ruby=None, runas=None, gem_bin=None):
|
||||
'''
|
||||
@ -45,7 +41,7 @@ def _gem(command, ruby=None, runas=None, gem_bin=None):
|
||||
:return:
|
||||
Returns the full standard out including success codes or False if it fails
|
||||
'''
|
||||
cmdline = '{gem} {command}'.format(gem=gem_bin or 'gem', command=command)
|
||||
cmdline = [gem_bin or 'gem'] + command
|
||||
|
||||
# If a custom gem is given, use that and don't check for rvm/rbenv. User
|
||||
# knows best!
|
||||
@ -53,22 +49,20 @@ def _gem(command, ruby=None, runas=None, gem_bin=None):
|
||||
if __salt__['rvm.is_installed'](runas=runas):
|
||||
return __salt__['rvm.do'](ruby, cmdline, runas=runas)
|
||||
|
||||
if not salt.utils.is_windows() and __salt__['rbenv.is_installed'](runas=runas):
|
||||
if not salt.utils.is_windows() \
|
||||
and __salt__['rbenv.is_installed'](runas=runas):
|
||||
if ruby is None:
|
||||
return __salt__['rbenv.do'](cmdline, runas=runas)
|
||||
else:
|
||||
return __salt__['rbenv.do_with_ruby'](ruby, cmdline, runas=runas)
|
||||
|
||||
ret = __salt__['cmd.run_all'](
|
||||
return __salt__['rbenv.do_with_ruby'](ruby,
|
||||
cmdline,
|
||||
runas=runas,
|
||||
python_shell=True
|
||||
)
|
||||
runas=runas)
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmdline, runas=runas, python_shell=False)
|
||||
|
||||
if ret['retcode'] == 0:
|
||||
return ret['stdout']
|
||||
else:
|
||||
logger.error(ret['stderr'])
|
||||
raise CommandExecutionError(ret['stderr'])
|
||||
|
||||
|
||||
@ -118,19 +112,14 @@ def install(gems, # pylint: disable=C0103
|
||||
|
||||
salt '*' gem.install redphone gem_bin=/opt/sensu/embedded/bin/gem
|
||||
'''
|
||||
|
||||
# Check for injection
|
||||
if gems:
|
||||
gems = ' '.join([_cmd_quote(gem) for gem in gems.split()])
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
try:
|
||||
gems = gems.split()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
options = []
|
||||
if version:
|
||||
version = _cmd_quote(version) # injection check
|
||||
options.append('--version {0}'.format(version))
|
||||
options.extend(['--version', version])
|
||||
if not rdoc:
|
||||
options.append('--no-rdoc')
|
||||
if not ri:
|
||||
@ -138,14 +127,11 @@ def install(gems, # pylint: disable=C0103
|
||||
if pre_releases:
|
||||
options.append('--pre')
|
||||
if proxy:
|
||||
proxy = _cmd_quote(proxy) # injection check
|
||||
options.append('-p {0}'.format(proxy))
|
||||
options.extend(['-p', proxy])
|
||||
if source:
|
||||
options.append('--source {0}'.format(source))
|
||||
options.extend(['--source', source])
|
||||
|
||||
cmdline_args = ' '.join(options)
|
||||
return _gem('install {gems} {options}'.format(gems=gems,
|
||||
options=cmdline_args),
|
||||
return _gem(['install'] + gems + options,
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
@ -171,15 +157,12 @@ def uninstall(gems, ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.uninstall vagrant
|
||||
'''
|
||||
# Check for injection
|
||||
if gems:
|
||||
gems = ' '.join([_cmd_quote(gem) for gem in gems.split()])
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
try:
|
||||
gems = gems.split()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return _gem('uninstall {gems} -a -x'.format(gems=gems),
|
||||
return _gem(['uninstall'] + gems + ['-a', '-x'],
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
@ -205,15 +188,12 @@ def update(gems, ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.update vagrant
|
||||
'''
|
||||
# Check for injection
|
||||
if gems:
|
||||
gems = ' '.join([_cmd_quote(gem) for gem in gems.split()])
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
try:
|
||||
gems = gems.split()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
return _gem('update {gems}'.format(gems=gems),
|
||||
return _gem(['update'] + gems,
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
@ -239,15 +219,7 @@ def update_system(version='', ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.update_system
|
||||
'''
|
||||
# Check for injection
|
||||
if version:
|
||||
version = _cmd_quote(version)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('update --system {version}'.format(version=version),
|
||||
return _gem(['update', '--system', version],
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
@ -273,28 +245,21 @@ def list_(prefix='', ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.list
|
||||
'''
|
||||
gems = {}
|
||||
# Check for injection
|
||||
cmd = ['list']
|
||||
if prefix:
|
||||
prefix = _cmd_quote(prefix)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
stdout = _gem('list {prefix}'.format(prefix=prefix),
|
||||
cmd.append(prefix)
|
||||
stdout = _gem(cmd,
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
lines = stdout.splitlines()
|
||||
for line in lines:
|
||||
ret = {}
|
||||
for line in salt.utils.itertools.split(stdout, '\n'):
|
||||
match = re.match(r'^([^ ]+) \((.+)\)', line)
|
||||
if match:
|
||||
gem = match.group(1)
|
||||
versions = match.group(2).split(', ')
|
||||
gems[gem] = versions
|
||||
|
||||
return gems
|
||||
ret[gem] = versions
|
||||
return ret
|
||||
|
||||
|
||||
def list_upgrades(ruby=None,
|
||||
@ -319,20 +284,20 @@ def list_upgrades(ruby=None,
|
||||
|
||||
salt '*' gem.list_upgrades
|
||||
'''
|
||||
result = _gem('outdated',
|
||||
result = _gem(['outdated'],
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
outdated = {}
|
||||
for line in result.splitlines():
|
||||
ret = {}
|
||||
for line in salt.utils.itertools.split(result, '\n'):
|
||||
match = re.search(r'(\S+) \(\S+ < (\S+)\)', line)
|
||||
if match:
|
||||
name, version = match.groups()
|
||||
else:
|
||||
logger.error('Can\'t parse line {0!r}'.format(line))
|
||||
log.error('Can\'t parse line \'{0}\''.format(line))
|
||||
continue
|
||||
outdated[name] = version
|
||||
return outdated
|
||||
ret[name] = version
|
||||
return ret
|
||||
|
||||
|
||||
def sources_add(source_uri, ruby=None, runas=None, gem_bin=None):
|
||||
@ -355,15 +320,7 @@ def sources_add(source_uri, ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.sources_add http://rubygems.org/
|
||||
'''
|
||||
# Check for injection
|
||||
if source_uri:
|
||||
source_uri = _cmd_quote(source_uri)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('sources --add {source_uri}'.format(source_uri=source_uri),
|
||||
return _gem(['sources', '--add', source_uri],
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
@ -389,15 +346,7 @@ def sources_remove(source_uri, ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.sources_remove http://rubygems.org/
|
||||
'''
|
||||
# Check for injection
|
||||
if source_uri:
|
||||
source_uri = _cmd_quote(source_uri)
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
return _gem('sources --remove {source_uri}'.format(source_uri=source_uri),
|
||||
return _gem(['sources', '--remove', source_uri],
|
||||
ruby,
|
||||
gem_bin=gem_bin,
|
||||
runas=runas)
|
||||
@ -421,11 +370,5 @@ def sources_list(ruby=None, runas=None, gem_bin=None):
|
||||
|
||||
salt '*' gem.sources_list
|
||||
'''
|
||||
# Check for injection
|
||||
if ruby:
|
||||
ruby = _cmd_quote(ruby)
|
||||
if gem_bin:
|
||||
gem_bin = _cmd_quote(gem_bin)
|
||||
|
||||
ret = _gem('sources', ruby, gem_bin=gem_bin, runas=runas)
|
||||
ret = _gem(['sources'], ruby, gem_bin=gem_bin, runas=runas)
|
||||
return [] if ret is False else ret.splitlines()[2:]
|
||||
|
@ -2,8 +2,8 @@
|
||||
'''
|
||||
InfluxDB - A distributed time series database
|
||||
|
||||
Module to provide InfluxDB compatibility to Salt
|
||||
(compatible with InfluxDB version 0.5+)
|
||||
Module to provide InfluxDB compatibility to Salt (compatible with InfluxDB
|
||||
version 0.5+)
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
@ -63,7 +63,7 @@ def _client(user=None, password=None, host=None, port=None):
|
||||
|
||||
|
||||
def db_list(user=None, password=None, host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
List all InfluxDB databases
|
||||
|
||||
user
|
||||
@ -85,7 +85,7 @@ def db_list(user=None, password=None, host=None, port=None):
|
||||
salt '*' influxdb.db_list
|
||||
salt '*' influxdb.db_list <user> <password> <host> <port>
|
||||
|
||||
"""
|
||||
'''
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
return client.get_list_database()
|
||||
|
||||
@ -123,7 +123,7 @@ def db_exists(name, user=None, password=None, host=None, port=None):
|
||||
|
||||
|
||||
def db_create(name, user=None, password=None, host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
Create a database
|
||||
|
||||
name
|
||||
@ -147,16 +147,16 @@ def db_create(name, user=None, password=None, host=None, port=None):
|
||||
|
||||
salt '*' influxdb.db_create <name>
|
||||
salt '*' influxdb.db_create <name> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
if db_exists(name, user, password, host, port):
|
||||
log.info('DB {0!r} already exists'.format(name))
|
||||
log.info('DB \'{0}\' already exists'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
return client.create_database(name)
|
||||
|
||||
|
||||
def db_remove(name, user=None, password=None, host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
Remove a database
|
||||
|
||||
name
|
||||
@ -180,16 +180,16 @@ def db_remove(name, user=None, password=None, host=None, port=None):
|
||||
|
||||
salt '*' influxdb.db_remove <name>
|
||||
salt '*' influxdb.db_remove <name> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
if not db_exists(name, user, password, host, port):
|
||||
log.info('DB {0!r} does not exist'.format(name))
|
||||
log.info('DB \'{0}\' does not exist'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
return client.delete_database(name)
|
||||
|
||||
|
||||
def user_list(database=None, user=None, password=None, host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
List cluster admins or database users.
|
||||
|
||||
If a database is specified: it will return database users list.
|
||||
@ -217,7 +217,7 @@ def user_list(database=None, user=None, password=None, host=None, port=None):
|
||||
salt '*' influxdb.user_list
|
||||
salt '*' influxdb.user_list <database>
|
||||
salt '*' influxdb.user_list <database> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
if database:
|
||||
client.switch_database(database)
|
||||
@ -267,7 +267,7 @@ def user_exists(
|
||||
|
||||
def user_create(name, passwd, database=None, user=None, password=None,
|
||||
host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
Create a cluster admin or a database user.
|
||||
|
||||
If a database is specified: it will create database user.
|
||||
@ -301,13 +301,13 @@ def user_create(name, passwd, database=None, user=None, password=None,
|
||||
salt '*' influxdb.user_create <name> <passwd>
|
||||
salt '*' influxdb.user_create <name> <passwd> <database>
|
||||
salt '*' influxdb.user_create <name> <passwd> <database> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
if user_exists(name, database, user, password, host, port):
|
||||
if database:
|
||||
log.info('User {0!r} already exists for DB {1!r}'.format(
|
||||
log.info('User \'{0}\' already exists for DB \'{1}\''.format(
|
||||
name, database))
|
||||
else:
|
||||
log.info('Cluster admin {0!r} already exists'.format(name))
|
||||
log.info('Cluster admin \'{0}\' already exists'.format(name))
|
||||
return False
|
||||
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
@ -319,7 +319,7 @@ def user_create(name, passwd, database=None, user=None, password=None,
|
||||
|
||||
def user_chpass(name, passwd, database=None, user=None, password=None,
|
||||
host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
Change password for a cluster admin or a database user.
|
||||
|
||||
If a database is specified: it will update database user password.
|
||||
@ -353,13 +353,17 @@ def user_chpass(name, passwd, database=None, user=None, password=None,
|
||||
salt '*' influxdb.user_chpass <name> <passwd>
|
||||
salt '*' influxdb.user_chpass <name> <passwd> <database>
|
||||
salt '*' influxdb.user_chpass <name> <passwd> <database> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
if not user_exists(name, database, user, password, host, port):
|
||||
if database:
|
||||
log.info('User {0!r} does not exist for DB {1!r}'.format(
|
||||
name, database))
|
||||
log.info(
|
||||
'User \'{0}\' does not exist for DB \'{1}\''.format(
|
||||
name,
|
||||
database
|
||||
)
|
||||
)
|
||||
else:
|
||||
log.info('Cluster admin {0!r} does not exist'.format(name))
|
||||
log.info('Cluster admin \'{0}\' does not exist'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
if database:
|
||||
@ -370,7 +374,7 @@ def user_chpass(name, passwd, database=None, user=None, password=None,
|
||||
|
||||
def user_remove(name, database=None, user=None, password=None, host=None,
|
||||
port=None):
|
||||
"""
|
||||
'''
|
||||
Remove a cluster admin or a database user.
|
||||
|
||||
If a database is specified: it will remove the database user.
|
||||
@ -404,13 +408,16 @@ def user_remove(name, database=None, user=None, password=None, host=None,
|
||||
salt '*' influxdb.user_remove <name>
|
||||
salt '*' influxdb.user_remove <name> <database>
|
||||
salt '*' influxdb.user_remove <name> <database> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
if not user_exists(name, database, user, password, host, port):
|
||||
if database:
|
||||
log.info('User {0!r} does not exist for DB {1!r}'.format(
|
||||
name, database))
|
||||
log.info(
|
||||
'User \'{0}\' does not exist for DB \'{1}\''.format(
|
||||
name, database
|
||||
)
|
||||
)
|
||||
else:
|
||||
log.info('Cluster admin {0!r} does not exist'.format(name))
|
||||
log.info('Cluster admin \'{0}\' does not exist'.format(name))
|
||||
return False
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
if database:
|
||||
@ -421,7 +428,7 @@ def user_remove(name, database=None, user=None, password=None, host=None,
|
||||
|
||||
def query(database, query, time_precision='s', chunked=False, user=None,
|
||||
password=None, host=None, port=None):
|
||||
"""
|
||||
'''
|
||||
Querying data
|
||||
|
||||
database
|
||||
@ -454,7 +461,7 @@ def query(database, query, time_precision='s', chunked=False, user=None,
|
||||
|
||||
salt '*' influxdb.query <database> <query>
|
||||
salt '*' influxdb.query <database> <query> <time_precision> <chunked> <user> <password> <host> <port>
|
||||
"""
|
||||
'''
|
||||
client = _client(user=user, password=password, host=host, port=port)
|
||||
client.switch_database(database)
|
||||
return client.query(query, time_precision=time_precision, chunked=chunked)
|
||||
|
@ -12,6 +12,7 @@ except ImportError:
|
||||
|
||||
# Import Salt Libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
from salt.modules.mac_user import _dscl, _flush_dscl_cache
|
||||
|
||||
@ -44,7 +45,9 @@ def add(name, gid=None, **kwargs):
|
||||
### NOTE: **kwargs isn't used here but needs to be included in this
|
||||
### function for compatibility with the group.present state
|
||||
if info(name):
|
||||
raise CommandExecutionError('Group {0!r} already exists'.format(name))
|
||||
raise CommandExecutionError(
|
||||
'Group \'{0}\' already exists'.format(name)
|
||||
)
|
||||
if salt.utils.contains_whitespace(name):
|
||||
raise SaltInvocationError('Group name cannot contain whitespace')
|
||||
if name.startswith('_'):
|
||||
@ -57,28 +60,30 @@ def add(name, gid=None, **kwargs):
|
||||
gid_list = _list_gids()
|
||||
if str(gid) in gid_list:
|
||||
raise CommandExecutionError(
|
||||
'gid {0!r} already exists'.format(gid)
|
||||
'gid \'{0}\' already exists'.format(gid)
|
||||
)
|
||||
|
||||
cmd = 'dseditgroup -o create '
|
||||
cmd = ['dseditgroup', '-o', 'create']
|
||||
if gid:
|
||||
cmd += '-i {0} '.format(gid)
|
||||
cmd += str(name)
|
||||
return __salt__['cmd.retcode'](cmd) == 0
|
||||
cmd.extend(['-i', gid])
|
||||
cmd.append(name)
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def _list_gids():
|
||||
'''
|
||||
Return a list of gids in use
|
||||
'''
|
||||
cmd = __salt__['cmd.run']('dscacheutil -q group | grep gid:',
|
||||
output = __salt__['cmd.run'](
|
||||
['dscacheutil', '-q', 'group'],
|
||||
output_loglevel='quiet',
|
||||
python_shell=True)
|
||||
data_list = cmd.split()
|
||||
for item in data_list:
|
||||
if item == 'gid:':
|
||||
data_list.remove(item)
|
||||
return sorted(set(data_list))
|
||||
python_shell=False
|
||||
)
|
||||
ret = set()
|
||||
for line in salt.utils.itertools.split(output, '\n'):
|
||||
if line.startswith('gid:'):
|
||||
ret.update(line.split()[1:])
|
||||
return sorted(ret)
|
||||
|
||||
|
||||
def delete(name):
|
||||
@ -99,8 +104,8 @@ def delete(name):
|
||||
)
|
||||
if not info(name):
|
||||
return True
|
||||
cmd = 'dseditgroup -o delete {0}'.format(name)
|
||||
return __salt__['cmd.retcode'](cmd) == 0
|
||||
cmd = ['dseditgroup', '-o', 'delete', name]
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def adduser(group, name):
|
||||
@ -235,8 +240,10 @@ def chgid(name, gid):
|
||||
pre_gid = __salt__['file.group_to_gid'](name)
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError('Group {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError(
|
||||
'Group \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if gid == pre_info['gid']:
|
||||
return True
|
||||
cmd = 'dseditgroup -o edit -i {0} {1}'.format(gid, name)
|
||||
return __salt__['cmd.retcode'](cmd) == 0
|
||||
cmd = ['dseditgroup', '-o', 'edit', '-i', gid, name]
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
@ -22,11 +22,6 @@ import salt.utils
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
from salt.ext.six import string_types
|
||||
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Define the module's virtual name
|
||||
@ -45,7 +40,7 @@ def _flush_dscl_cache():
|
||||
'''
|
||||
Flush dscl cache
|
||||
'''
|
||||
__salt__['cmd.run']('dscacheutil -flushcache')
|
||||
__salt__['cmd.run'](['dscacheutil', '-flushcache'], python_shell=False)
|
||||
|
||||
|
||||
def _dscl(cmd, ctype='create'):
|
||||
@ -56,11 +51,13 @@ def _dscl(cmd, ctype='create'):
|
||||
source, noderoot = '.', ''
|
||||
else:
|
||||
source, noderoot = 'localhost', '/Local/Default'
|
||||
if noderoot:
|
||||
cmd[0] = noderoot + cmd[0]
|
||||
|
||||
# Note, it's OK that cmd is not quoted here, we clean it up below
|
||||
return __salt__['cmd.run_all'](
|
||||
'dscl {0} -{1} {2}{3}'.format(source, ctype, noderoot, cmd),
|
||||
output_loglevel='quiet' if ctype == 'passwd' else 'warning'
|
||||
['dscl', source, '-' + ctype] + cmd,
|
||||
output_loglevel='quiet' if ctype == 'passwd' else 'debug',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -90,7 +87,7 @@ def add(name,
|
||||
salt '*' user.add name <uid> <gid> <groups> <home> <shell>
|
||||
'''
|
||||
if info(name):
|
||||
raise CommandExecutionError('User {0!r} already exists'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' already exists'.format(name))
|
||||
|
||||
if salt.utils.contains_whitespace(name):
|
||||
raise SaltInvocationError('Username cannot contain whitespace')
|
||||
@ -112,22 +109,20 @@ def add(name,
|
||||
if not isinstance(gid, int):
|
||||
raise SaltInvocationError('gid must be an integer')
|
||||
|
||||
_dscl('/Users/{0} UniqueID {1!r}'.format(_cmd_quote(name), uid))
|
||||
_dscl('/Users/{0} PrimaryGroupID {1!r}'.format(_cmd_quote(name), gid))
|
||||
_dscl('/Users/{0} UserShell {1!r}'.format(_cmd_quote(name),
|
||||
_cmd_quote(shell)))
|
||||
_dscl('/Users/{0} NFSHomeDirectory {1!r}'.format(_cmd_quote(name),
|
||||
_cmd_quote(home)))
|
||||
_dscl('/Users/{0} RealName {1!r}'.format(_cmd_quote(name),
|
||||
_cmd_quote(fullname)))
|
||||
name_path = '/Users/{0}'.format(name)
|
||||
_dscl([name_path, 'UniqueID', uid])
|
||||
_dscl([name_path, 'PrimaryGroupID', gid])
|
||||
_dscl([name_path, 'UserShell', shell])
|
||||
_dscl([name_path, 'NFSHomeDirectory', home])
|
||||
_dscl([name_path, 'RealName', fullname])
|
||||
|
||||
# Set random password, since without a password the account will not be
|
||||
# available. TODO: add shadow module
|
||||
randpass = ''.join(
|
||||
random.SystemRandom().choice(string.letters + string.digits) for x in range(20)
|
||||
random.SystemRandom().choice(string.letters + string.digits)
|
||||
for x in range(20)
|
||||
)
|
||||
_dscl('/Users/{0} {1!r}'.format(_cmd_quote(name),
|
||||
_cmd_quote(randpass)), ctype='passwd')
|
||||
_dscl([name_path, randpass], ctype='passwd')
|
||||
|
||||
# dscl buffers changes, sleep before setting group membership
|
||||
time.sleep(1)
|
||||
@ -156,7 +151,7 @@ def delete(name, *args):
|
||||
# group membership is managed separately from users and an entry for the
|
||||
# user will persist even after the user is removed.
|
||||
chgroups(name, ())
|
||||
return _dscl('/Users/{0}'.format(_cmd_quote(name)), ctype='delete')['retcode'] == 0
|
||||
return _dscl(['/Users/{0}'.format(name)], ctype='delete')['retcode'] == 0
|
||||
|
||||
|
||||
def getent(refresh=False):
|
||||
@ -193,13 +188,11 @@ def chuid(name, uid):
|
||||
raise SaltInvocationError('uid must be an integer')
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
if uid == pre_info['uid']:
|
||||
return True
|
||||
_dscl(
|
||||
'/Users/{0} UniqueID {1!r} {2!r}'.format(_cmd_quote(name),
|
||||
pre_info['uid'],
|
||||
uid),
|
||||
['/Users/{0}'.format(name), 'UniqueID', pre_info['uid'], uid],
|
||||
ctype='change'
|
||||
)
|
||||
# dscl buffers changes, sleep 1 second before checking if new value
|
||||
@ -222,14 +215,11 @@ def chgid(name, gid):
|
||||
raise SaltInvocationError('gid must be an integer')
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
if gid == pre_info['gid']:
|
||||
return True
|
||||
_dscl(
|
||||
'/Users/{0} PrimaryGroupID {1!r} {2!r}'.format(
|
||||
_cmd_quote(name),
|
||||
pre_info['gid'],
|
||||
gid),
|
||||
['/Users/{0}'.format(name), 'PrimaryGroupID', pre_info['gid'], gid],
|
||||
ctype='change'
|
||||
)
|
||||
# dscl buffers changes, sleep 1 second before checking if new value
|
||||
@ -250,14 +240,11 @@ def chshell(name, shell):
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
if shell == pre_info['shell']:
|
||||
return True
|
||||
_dscl(
|
||||
'/Users/{0} UserShell {1!r} {2!r}'.format(
|
||||
_cmd_quote(name),
|
||||
_cmd_quote(pre_info['shell']),
|
||||
_cmd_quote(shell)),
|
||||
['/Users/{0}'.format(name), 'UserShell', pre_info['shell'], shell],
|
||||
ctype='change'
|
||||
)
|
||||
# dscl buffers changes, sleep 1 second before checking if new value
|
||||
@ -278,14 +265,12 @@ def chhome(name, home):
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
if home == pre_info['home']:
|
||||
return True
|
||||
_dscl(
|
||||
'/Users/{0} NFSHomeDirectory {1!r} {2!r}'.format(
|
||||
_cmd_quote(name),
|
||||
_cmd_quote(pre_info['home']),
|
||||
_cmd_quote(home)),
|
||||
['/Users/{0}'.format(name), 'NFSHomeDirectory',
|
||||
pre_info['home'], home],
|
||||
ctype='change'
|
||||
)
|
||||
# dscl buffers changes, sleep 1 second before checking if new value
|
||||
@ -307,13 +292,13 @@ def chfullname(name, fullname):
|
||||
fullname = str(fullname)
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
if fullname == pre_info['fullname']:
|
||||
return True
|
||||
_dscl(
|
||||
'/Users/{0} RealName {1!r}'.format(_cmd_quote(name), fullname),
|
||||
# use a "create" command, because a "change" command would fail if
|
||||
# current fullname is an empty string. The "create" will just overwrite
|
||||
['/Users/{0}'.format(name), 'RealName', fullname],
|
||||
# use a 'create' command, because a 'change' command would fail if
|
||||
# current fullname is an empty string. The 'create' will just overwrite
|
||||
# this field.
|
||||
ctype='create'
|
||||
)
|
||||
@ -347,7 +332,7 @@ def chgroups(name, groups, append=False):
|
||||
### function for compatibility with the user.present state
|
||||
uinfo = info(name)
|
||||
if not uinfo:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
if isinstance(groups, string_types):
|
||||
groups = groups.split(',')
|
||||
|
||||
@ -366,16 +351,14 @@ def chgroups(name, groups, append=False):
|
||||
# Add groups from which user is missing
|
||||
for group in desired - ugrps:
|
||||
_dscl(
|
||||
'/Groups/{0} GroupMembership {1}'.format(_cmd_quote(group),
|
||||
_cmd_quote(name)),
|
||||
['/Groups/{0}'.format(group), 'GroupMembership', name],
|
||||
ctype='append'
|
||||
)
|
||||
if not append:
|
||||
# Remove from extra groups
|
||||
for group in ugrps - desired:
|
||||
_dscl(
|
||||
'/Groups/{0} GroupMembership {1}'.format(_cmd_quote(group),
|
||||
_cmd_quote(name)),
|
||||
['/Groups/{0}'.format(group), 'GroupMembership', name],
|
||||
ctype='delete'
|
||||
)
|
||||
time.sleep(1)
|
||||
@ -423,7 +406,8 @@ def list_groups(name):
|
||||
|
||||
salt '*' user.list_groups foo
|
||||
'''
|
||||
groups = [group for group in salt.utils.get_group_list(name) if not group.startswith('_')]
|
||||
groups = [group for group in salt.utils.get_group_list(name)
|
||||
if not group.startswith('_')]
|
||||
return groups
|
||||
|
||||
|
||||
@ -452,12 +436,14 @@ def rename(name, new_name):
|
||||
'''
|
||||
current_info = info(name)
|
||||
if not current_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
new_info = info(new_name)
|
||||
if new_info:
|
||||
raise CommandExecutionError('User {0!r} already exists'.format(new_name))
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' already exists'.format(new_name)
|
||||
)
|
||||
_dscl(
|
||||
'/Users/{0} RecordName {0!r} {2!r}'.format(name, new_name),
|
||||
['/Users/{0}'.format(name), 'RecordName', name, new_name],
|
||||
ctype='change'
|
||||
)
|
||||
# dscl buffers changes, sleep 1 second before checking if new value
|
||||
|
@ -222,10 +222,10 @@ def increment(key, delta=1, host=DEFAULT_HOST, port=DEFAULT_PORT):
|
||||
cur = get(key)
|
||||
|
||||
if cur is None:
|
||||
raise CommandExecutionError('Key {0!r} does not exist'.format(key))
|
||||
raise CommandExecutionError('Key \'{0}\' does not exist'.format(key))
|
||||
elif not isinstance(cur, integer_types):
|
||||
raise CommandExecutionError(
|
||||
'Value for key {0!r} must be an integer to be '
|
||||
'Value for key \'{0}\' must be an integer to be '
|
||||
'incremented'.format(key)
|
||||
)
|
||||
|
||||
@ -253,10 +253,10 @@ def decrement(key, delta=1, host=DEFAULT_HOST, port=DEFAULT_PORT):
|
||||
|
||||
cur = get(key)
|
||||
if cur is None:
|
||||
raise CommandExecutionError('Key {0!r} does not exist'.format(key))
|
||||
raise CommandExecutionError('Key \'{0}\' does not exist'.format(key))
|
||||
elif not isinstance(cur, integer_types):
|
||||
raise CommandExecutionError(
|
||||
'Value for key {0!r} must be an integer to be '
|
||||
'Value for key \'{0}\' must be an integer to be '
|
||||
'decremented'.format(key)
|
||||
)
|
||||
|
||||
|
@ -26,12 +26,11 @@ Module to provide MySQL compatibility to salt.
|
||||
mysql.default_file: '/etc/mysql/debian.cnf'
|
||||
|
||||
.. versionchanged:: 2014.1.0
|
||||
charset connection argument added. This is a MySQL charset, not a python one
|
||||
\'charset\' connection argument added. This is a MySQL charset, not a python one.
|
||||
.. versionchanged:: 0.16.2
|
||||
Connection arguments from the minion config file can be overridden on the
|
||||
CLI by using the arguments defined :doc:`here
|
||||
</ref/states/all/salt.states.mysql_user>`. Additionally, it is now possible
|
||||
to setup a user with no password.
|
||||
CLI by using the arguments defined :mod:`here <salt.states.mysql_user>`.
|
||||
Additionally, it is now possible to setup a user with no password.
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
@ -119,68 +118,76 @@ __ssl_options__ = __ssl_options_parameterized__ + [
|
||||
'X509'
|
||||
]
|
||||
|
||||
################################################################################
|
||||
# DEVELOPER NOTE: ABOUT arguments management, escapes, formats, arguments and
|
||||
# security of SQL.
|
||||
#
|
||||
# A general rule of SQL security is to use queries with _execute call in this
|
||||
# code using args parameter to let MySQLdb manage the arguments proper escaping.
|
||||
# Another way of escaping values arguments could be '{0!r}'.format(), using
|
||||
# __repr__ to ensure things get properly used as strings. But this could lead
|
||||
# to two problems:
|
||||
#
|
||||
# * In ANSI mode, which is available on MySQL, but not by default, double
|
||||
# quotes " should not be used as a string delimiters, in ANSI mode this is an
|
||||
# identifier delimiter (like `).
|
||||
#
|
||||
# * Some rare exploits with bad multibytes management, either on python or
|
||||
# MySQL could defeat this barrier, bindings internal escape functions
|
||||
# should manage theses cases.
|
||||
#
|
||||
# So query with arguments should use a paramstyle defined in PEP249:
|
||||
#
|
||||
# http://www.python.org/dev/peps/pep-0249/#paramstyle
|
||||
# We use pyformat, which means 'SELECT * FROM foo WHERE bar=%(myval)s'
|
||||
# used with {'myval': 'some user input'}
|
||||
#
|
||||
# So far so good. But this cannot be used for identifier escapes. Identifiers
|
||||
# are database names, table names and column names. Theses names are not values
|
||||
# and do not follow the same escape rules (see quote_identifier function for
|
||||
# details on `_ and % escape policies on identifiers). Using value escaping on
|
||||
# identifier could fool the SQL engine (badly escaping quotes and not doubling
|
||||
# ` characters. So for identifiers a call to quote_identifier should be done and
|
||||
# theses identifiers should then be added in strings with format, but without
|
||||
# __repr__ filter.
|
||||
#
|
||||
# Note also that when using query with arguments in _execute all '%' characters
|
||||
# used in the query should get escaped to '%%' fo MySQLdb, but should not be
|
||||
# escaped if the query runs without arguments. This is managed by _execute() and
|
||||
# quote_identifier. This is not the same as escaping '%' to '\%' or '_' to '\%'
|
||||
# when using a LIKE query (example in db_exists), as this escape is there to
|
||||
# avoid having _ or % characters interpreted in LIKE queries. The string parted
|
||||
# of the first query could become (still used with args dictionary for myval):
|
||||
# 'SELECT * FROM {0} WHERE bar=%(myval)s'.format(quote_identifier('user input'))
|
||||
#
|
||||
# Check integration tests if you find a hole in theses strings and escapes rules
|
||||
#
|
||||
# Finally some examples to sum up.
|
||||
#
|
||||
# Given a name f_o%o`b'a"r, in python that would be '''f_o%o`b'a"r'''. I'll
|
||||
# avoid python syntax for clarity:
|
||||
#
|
||||
# The MySQL way of writing this name is:
|
||||
#
|
||||
# value : 'f_o%o`b\'a"r' (managed by MySQLdb)
|
||||
# identifier : `f_o%o``b'a"r`
|
||||
# db identifier in general GRANT: `f\_o\%o``b'a"r`
|
||||
# db identifier in table GRANT : `f_o%o``b'a"r`
|
||||
# in mySQLdb, query with args : `f_o%%o``b'a"r` (as identifier)
|
||||
# in mySQLdb, query without args: `f_o%o``b'a"r` (as identifier)
|
||||
# value in a LIKE query : 'f\_o\%o`b\'a"r' (quotes managed by MySQLdb)
|
||||
#
|
||||
# And theses could be mixed, in a like query value with args: 'f\_o\%%o`b\'a"r'
|
||||
#
|
||||
################################################################################
|
||||
r'''
|
||||
DEVELOPER NOTE: ABOUT arguments management, escapes, formats, arguments and
|
||||
security of SQL.
|
||||
|
||||
A general rule of SQL security is to use queries with _execute call in this
|
||||
code using args parameter to let MySQLdb manage the arguments proper escaping.
|
||||
Another way of escaping values arguments could be '{0!r}'.format(), using
|
||||
__repr__ to ensure things get properly used as strings. But this could lead
|
||||
to three problems:
|
||||
|
||||
* In ANSI mode, which is available on MySQL, but not by default, double
|
||||
quotes " should not be used as a string delimiters, in ANSI mode this is an
|
||||
identifier delimiter (like `).
|
||||
|
||||
* Some rare exploits with bad multibytes management, either on python or
|
||||
MySQL could defeat this barrier, bindings internal escape functions
|
||||
should manage theses cases.
|
||||
|
||||
* Unicode strings in Python 2 will include the 'u' before the repr'ed string,
|
||||
like so:
|
||||
|
||||
Python 2.7.10 (default, May 26 2015, 04:16:29)
|
||||
[GCC 5.1.0] on linux2
|
||||
Type "help", "copyright", "credits" or "license" for more information.
|
||||
>>> u'something something {0!r}'.format(u'foo')
|
||||
u"something something u'foo'"
|
||||
|
||||
So query with arguments should use a paramstyle defined in PEP249:
|
||||
|
||||
http://www.python.org/dev/peps/pep-0249/#paramstyle
|
||||
We use pyformat, which means 'SELECT * FROM foo WHERE bar=%(myval)s'
|
||||
used with {'myval': 'some user input'}
|
||||
|
||||
So far so good. But this cannot be used for identifier escapes. Identifiers
|
||||
are database names, table names and column names. Theses names are not values
|
||||
and do not follow the same escape rules (see quote_identifier function for
|
||||
details on `_ and % escape policies on identifiers). Using value escaping on
|
||||
identifier could fool the SQL engine (badly escaping quotes and not doubling
|
||||
` characters. So for identifiers a call to quote_identifier should be done and
|
||||
theses identifiers should then be added in strings with format, but without
|
||||
__repr__ filter.
|
||||
|
||||
Note also that when using query with arguments in _execute all '%' characters
|
||||
used in the query should get escaped to '%%' fo MySQLdb, but should not be
|
||||
escaped if the query runs without arguments. This is managed by _execute() and
|
||||
quote_identifier. This is not the same as escaping '%' to '\%' or '_' to '\%'
|
||||
when using a LIKE query (example in db_exists), as this escape is there to
|
||||
avoid having _ or % characters interpreted in LIKE queries. The string parted
|
||||
of the first query could become (still used with args dictionary for myval):
|
||||
'SELECT * FROM {0} WHERE bar=%(myval)s'.format(quote_identifier('user input'))
|
||||
|
||||
Check integration tests if you find a hole in theses strings and escapes rules
|
||||
|
||||
Finally some examples to sum up.
|
||||
|
||||
Given a name f_o%o`b'a"r, in python that would be """f_o%o`b'a"r""". I'll
|
||||
avoid python syntax for clarity:
|
||||
|
||||
The MySQL way of writing this name is:
|
||||
|
||||
value : 'f_o%o`b\'a"r' (managed by MySQLdb)
|
||||
identifier : `f_o%o``b'a"r`
|
||||
db identifier in general GRANT: `f\_o\%o``b'a"r`
|
||||
db identifier in table GRANT : `f_o%o``b'a"r`
|
||||
in mySQLdb, query with args : `f_o%%o``b'a"r` (as identifier)
|
||||
in mySQLdb, query without args: `f_o%o``b'a"r` (as identifier)
|
||||
value in a LIKE query : 'f\_o\%o`b\'a"r' (quotes managed by MySQLdb)
|
||||
|
||||
And theses could be mixed, in a like query value with args: 'f\_o\%%o`b\'a"r'
|
||||
'''
|
||||
|
||||
|
||||
def __virtual__():
|
||||
@ -342,7 +349,7 @@ def _grant_to_tokens(grant):
|
||||
- grant: [grant1, grant2] (ala SELECT, USAGE, etc)
|
||||
- database: MySQL DB
|
||||
'''
|
||||
log.debug('_grant_to_tokens entry {0!r}'.format(grant))
|
||||
log.debug('_grant_to_tokens entry \'{0}\''.format(grant))
|
||||
dict_mode = False
|
||||
if isinstance(grant, dict):
|
||||
dict_mode = True
|
||||
@ -386,7 +393,7 @@ def _grant_to_tokens(grant):
|
||||
position_tracker = 1 # Skip the initial 'GRANT' word token
|
||||
database = ''
|
||||
phrase = 'grants'
|
||||
#log.debug('_grant_to_tokens lex analysis {0!r}'.format(exploded_grant))
|
||||
#log.debug('_grant_to_tokens lex analysis \'{0}\''.format(exploded_grant))
|
||||
|
||||
for token in exploded_grant[position_tracker:]:
|
||||
|
||||
@ -455,12 +462,14 @@ def _grant_to_tokens(grant):
|
||||
if not dict_mode:
|
||||
user = user.strip("'")
|
||||
host = host.strip("'")
|
||||
log.debug('grant to token {0!r}::{1!r}::{2!r}::{3!r}'.format(
|
||||
log.debug(
|
||||
'grant to token \'{0}\'::\'{1}\'::\'{2}\'::\'{3}\''.format(
|
||||
user,
|
||||
host,
|
||||
grant_tokens,
|
||||
database
|
||||
))
|
||||
)
|
||||
)
|
||||
except UnboundLocalError:
|
||||
host = ''
|
||||
|
||||
@ -836,7 +845,7 @@ def db_tables(name, **connection_args):
|
||||
salt '*' mysql.db_tables 'database'
|
||||
'''
|
||||
if not db_exists(name, **connection_args):
|
||||
log.info('Database {0!r} does not exist'.format(name,))
|
||||
log.info('Database \'{0}\' does not exist'.format(name))
|
||||
return False
|
||||
|
||||
dbc = _connect(**connection_args)
|
||||
@ -914,7 +923,7 @@ def db_create(name, character_set=None, collate=None, **connection_args):
|
||||
'''
|
||||
# check if db exists
|
||||
if db_exists(name, **connection_args):
|
||||
log.info('DB {0!r} already exists'.format(name))
|
||||
log.info('DB \'{0}\' already exists'.format(name))
|
||||
return False
|
||||
|
||||
# db doesn't exist, proceed
|
||||
@ -936,7 +945,7 @@ def db_create(name, character_set=None, collate=None, **connection_args):
|
||||
|
||||
try:
|
||||
if _execute(cur, qry, args):
|
||||
log.info('DB {0!r} created'.format(name))
|
||||
log.info('DB \'{0}\' created'.format(name))
|
||||
return True
|
||||
except MySQLdb.OperationalError as exc:
|
||||
err = 'MySQL Error {0}: {1}'.format(*exc)
|
||||
@ -957,11 +966,11 @@ def db_remove(name, **connection_args):
|
||||
'''
|
||||
# check if db exists
|
||||
if not db_exists(name, **connection_args):
|
||||
log.info('DB {0!r} does not exist'.format(name))
|
||||
log.info('DB \'{0}\' does not exist'.format(name))
|
||||
return False
|
||||
|
||||
if name in ('mysql', 'information_scheme'):
|
||||
log.info('DB {0!r} may not be removed'.format(name))
|
||||
log.info('DB \'{0}\' may not be removed'.format(name))
|
||||
return False
|
||||
|
||||
# db does exists, proceed
|
||||
@ -981,10 +990,10 @@ def db_remove(name, **connection_args):
|
||||
return False
|
||||
|
||||
if not db_exists(name, **connection_args):
|
||||
log.info('Database {0!r} has been removed'.format(name))
|
||||
log.info('Database \'{0}\' has been removed'.format(name))
|
||||
return True
|
||||
|
||||
log.info('Database {0!r} has not been removed'.format(name))
|
||||
log.info('Database \'{0}\' has not been removed'.format(name))
|
||||
return False
|
||||
|
||||
|
||||
@ -1166,7 +1175,7 @@ def user_create(user,
|
||||
salt '*' mysql.user_create 'username' 'hostname' allow_passwordless=True
|
||||
'''
|
||||
if user_exists(user, host, **connection_args):
|
||||
log.info('User {0!r}@{1!r} already exists'.format(user, host))
|
||||
log.info('User \'{0}\'@\'{1}\' already exists'.format(user, host))
|
||||
return False
|
||||
|
||||
dbc = _connect(**connection_args)
|
||||
@ -1206,13 +1215,13 @@ def user_create(user,
|
||||
return False
|
||||
|
||||
if user_exists(user, host, password, password_hash, **connection_args):
|
||||
msg = 'User {0!r}@{1!r} has been created'.format(user, host)
|
||||
msg = 'User \'{0}\'@\'{1}\' has been created'.format(user, host)
|
||||
if not any((password, password_hash)):
|
||||
msg += ' with passwordless login'
|
||||
log.info(msg)
|
||||
return True
|
||||
|
||||
log.info('User {0!r}@{1!r} was not created'.format(user, host))
|
||||
log.info('User \'{0}\'@\'{1}\' was not created'.format(user, host))
|
||||
return False
|
||||
|
||||
|
||||
@ -1302,7 +1311,7 @@ def user_chpass(user,
|
||||
if result:
|
||||
_execute(cur, 'FLUSH PRIVILEGES;')
|
||||
log.info(
|
||||
'Password for user {0!r}@{1!r} has been {2}'.format(
|
||||
'Password for user \'{0}\'@\'{1}\' has been {2}'.format(
|
||||
user, host,
|
||||
'changed' if any((password, password_hash)) else 'cleared'
|
||||
)
|
||||
@ -1310,7 +1319,7 @@ def user_chpass(user,
|
||||
return True
|
||||
|
||||
log.info(
|
||||
'Password for user {0!r}@{1!r} was not {2}'.format(
|
||||
'Password for user \'{0}\'@\'{1}\' was not {2}'.format(
|
||||
user, host,
|
||||
'changed' if any((password, password_hash)) else 'cleared'
|
||||
)
|
||||
@ -1348,10 +1357,10 @@ def user_remove(user,
|
||||
return False
|
||||
|
||||
if not user_exists(user, host, **connection_args):
|
||||
log.info('User {0!r}@{1!r} has been removed'.format(user, host))
|
||||
log.info('User \'{0}\'@\'{1}\' has been removed'.format(user, host))
|
||||
return True
|
||||
|
||||
log.info('User {0!r}@{1!r} has NOT been removed'.format(user, host))
|
||||
log.info('User \'{0}\'@\'{1}\' has NOT been removed'.format(user, host))
|
||||
return False
|
||||
|
||||
|
||||
@ -1391,11 +1400,11 @@ def db_check(name,
|
||||
tables = db_tables(name, **connection_args)
|
||||
for table in tables:
|
||||
log.info(
|
||||
'Checking table {0!r} in db {1!r}..'.format(name, table)
|
||||
'Checking table \'{0}\' in db \'{1}\'..'.format(name, table)
|
||||
)
|
||||
ret.append(__check_table(name, table, **connection_args))
|
||||
else:
|
||||
log.info('Checking table {0!r} in db {1!r}..'.format(name, table))
|
||||
log.info('Checking table \'{0}\' in db \'{1}\'..'.format(name, table))
|
||||
ret = __check_table(name, table, **connection_args)
|
||||
return ret
|
||||
|
||||
@ -1418,11 +1427,11 @@ def db_repair(name,
|
||||
tables = db_tables(name, **connection_args)
|
||||
for table in tables:
|
||||
log.info(
|
||||
'Repairing table {0!r} in db {1!r}..'.format(name, table)
|
||||
'Repairing table \'{0}\' in db \'{1}\'..'.format(name, table)
|
||||
)
|
||||
ret.append(__repair_table(name, table, **connection_args))
|
||||
else:
|
||||
log.info('Repairing table {0!r} in db {1!r}..'.format(name, table))
|
||||
log.info('Repairing table \'{0}\' in db \'{1}\'..'.format(name, table))
|
||||
ret = __repair_table(name, table, **connection_args)
|
||||
return ret
|
||||
|
||||
@ -1445,12 +1454,12 @@ def db_optimize(name,
|
||||
tables = db_tables(name, **connection_args)
|
||||
for table in tables:
|
||||
log.info(
|
||||
'Optimizing table {0!r} in db {1!r}..'.format(name, table)
|
||||
'Optimizing table \'{0}\' in db \'{1}\'..'.format(name, table)
|
||||
)
|
||||
ret.append(__optimize_table(name, table, **connection_args))
|
||||
else:
|
||||
log.info(
|
||||
'Optimizing table {0!r} in db {1!r}..'.format(name, table)
|
||||
'Optimizing table \'{0}\' in db \'{1}\'..'.format(name, table)
|
||||
)
|
||||
ret = __optimize_table(name, table, **connection_args)
|
||||
return ret
|
||||
@ -1467,7 +1476,7 @@ def __grant_normalize(grant):
|
||||
exploded_grants = grant.split(",")
|
||||
for chkgrant in exploded_grants:
|
||||
if chkgrant.strip().upper() not in __grants__:
|
||||
raise Exception('Invalid grant : {0!r}'.format(
|
||||
raise Exception('Invalid grant : \'{0}\''.format(
|
||||
chkgrant
|
||||
))
|
||||
|
||||
@ -1484,7 +1493,7 @@ def __ssl_option_sanitize(ssl_option):
|
||||
normal_key = key.strip().upper()
|
||||
|
||||
if normal_key not in __ssl_options__:
|
||||
raise Exception('Invalid SSL option : {0!r}'.format(
|
||||
raise Exception('Invalid SSL option : \'{0}\''.format(
|
||||
key
|
||||
))
|
||||
|
||||
@ -1554,7 +1563,7 @@ def user_grants(user,
|
||||
salt '*' mysql.user_grants 'frank' 'localhost'
|
||||
'''
|
||||
if not user_exists(user, host, **connection_args):
|
||||
log.info('User {0!r}@{1!r} does not exist'.format(user, host))
|
||||
log.info('User \'{0}\'@\'{1}\' does not exist'.format(user, host))
|
||||
return False
|
||||
|
||||
dbc = _connect(**connection_args)
|
||||
@ -1628,7 +1637,7 @@ def grant_exists(grant,
|
||||
set(grant_tokens['grant']) == set(target_tokens['grant']):
|
||||
return True
|
||||
else:
|
||||
log.debug('grants mismatch {0!r}<>{1!r}'.format(
|
||||
log.debug('grants mismatch \'{0}\'<>\'{1}\''.format(
|
||||
grant_tokens,
|
||||
target_tokens
|
||||
))
|
||||
@ -1686,14 +1695,14 @@ def grant_add(grant,
|
||||
grant, database, user, host, grant_option, escape,
|
||||
**connection_args):
|
||||
log.info(
|
||||
'Grant {0!r} on {1!r} for user {2!r} has been added'.format(
|
||||
'Grant \'{0}\' on \'{1}\' for user \'{2}\' has been added'.format(
|
||||
grant, database, user
|
||||
)
|
||||
)
|
||||
return True
|
||||
|
||||
log.info(
|
||||
'Grant {0!r} on {1!r} for user {2!r} has NOT been added'.format(
|
||||
'Grant \'{0}\' on \'{1}\' for user \'{2}\' has NOT been added'.format(
|
||||
grant, database, user
|
||||
)
|
||||
)
|
||||
@ -1767,13 +1776,13 @@ def grant_revoke(grant,
|
||||
escape,
|
||||
**connection_args):
|
||||
log.info(
|
||||
'Grant {0!r} on {1!r} for user {2!r} has been '
|
||||
'Grant \'{0}\' on \'{1}\' for user \'{2}\' has been '
|
||||
'revoked'.format(grant, database, user)
|
||||
)
|
||||
return True
|
||||
|
||||
log.info(
|
||||
'Grant {0!r} on {1!r} for user {2!r} has NOT been '
|
||||
'Grant \'{0}\' on \'{1}\' for user \'{2}\' has NOT been '
|
||||
'revoked'.format(grant, database, user)
|
||||
)
|
||||
return False
|
||||
|
@ -25,6 +25,7 @@ except ImportError:
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
from salt.utils.decorators import which as _which
|
||||
|
||||
from salt.exceptions import (
|
||||
@ -80,8 +81,10 @@ def latest_version(*names, **kwargs):
|
||||
refresh_db()
|
||||
|
||||
cmd = ['opkg', 'list-upgradable']
|
||||
out = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
out = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
try:
|
||||
name, _oldversion, newversion = line.split(' - ')
|
||||
if name in names:
|
||||
@ -133,8 +136,9 @@ def refresh_db():
|
||||
'''
|
||||
ret = {}
|
||||
cmd = ['opkg', 'update']
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
if 'stderr' in call:
|
||||
@ -146,7 +150,7 @@ def refresh_db():
|
||||
else:
|
||||
out = call['stdout']
|
||||
|
||||
for line in out.splitlines():
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if 'Inflating' in line:
|
||||
key = line.strip().split()[1].split('.')[0]
|
||||
ret[key] = True
|
||||
@ -239,7 +243,7 @@ def install(name=None,
|
||||
if refreshdb:
|
||||
refresh_db()
|
||||
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -281,7 +285,7 @@ def remove(name=None, pkgs=None, **kwargs): # pylint: disable=unused-argument
|
||||
return {}
|
||||
cmd = ['opkg', 'remove']
|
||||
cmd.extend(targets)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -342,7 +346,9 @@ def upgrade(refresh=True):
|
||||
old = list_pkgs()
|
||||
|
||||
cmd = ['opkg', 'upgrade']
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
||||
if call['retcode'] != 0:
|
||||
ret['result'] = False
|
||||
@ -508,9 +514,9 @@ def _get_state(pkg):
|
||||
'''
|
||||
cmd = ['opkg', 'status']
|
||||
cmd.append(pkg)
|
||||
out = __salt__['cmd.run'](cmd)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
state_flag = ''
|
||||
for line in out.splitlines():
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if line.startswith('Status'):
|
||||
_status, _state_want, state_flag, _state_status = line.split()
|
||||
|
||||
@ -546,7 +552,7 @@ def _set_state(pkg, state):
|
||||
cmd = ['opkg', 'flag']
|
||||
cmd.append(state)
|
||||
cmd.append(pkg)
|
||||
_out = __salt__['cmd.run'](cmd)
|
||||
_out = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
|
||||
# Missing return value check due to opkg issue 160
|
||||
ret[pkg] = {'old': oldstate,
|
||||
@ -583,8 +589,8 @@ def list_pkgs(versions_as_list=False, **kwargs):
|
||||
|
||||
cmd = ['opkg', 'list-installed']
|
||||
ret = {}
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
pkg_name, pkg_version = line.split(' - ')
|
||||
__salt__['pkg_resource.add_pkg'](ret, pkg_name, pkg_version)
|
||||
|
||||
@ -610,7 +616,9 @@ def list_upgrades(refresh=True):
|
||||
refresh_db()
|
||||
|
||||
cmd = ['opkg', 'list-upgradable']
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
@ -663,9 +671,10 @@ def version_cmp(pkg1, pkg2):
|
||||
cmd.append(_cmd_quote(pkg1))
|
||||
cmd.append(oper)
|
||||
cmd.append(_cmd_quote(pkg2))
|
||||
retcode = __salt__['cmd.retcode'](
|
||||
cmd, output_loglevel='trace', ignore_retcode=True
|
||||
)
|
||||
retcode = __salt__['cmd.retcode'](cmd,
|
||||
output_loglevel='trace',
|
||||
ignore_retcode=True,
|
||||
python_shell=False)
|
||||
if retcode == 0:
|
||||
return ret
|
||||
return None
|
||||
@ -803,9 +812,9 @@ def del_repo(alias):
|
||||
if source['file'] in deleted_from:
|
||||
deleted_from[source['file']] += 1
|
||||
for repo_file, count in six.iteritems(deleted_from):
|
||||
msg = 'Repo {0!r} has been removed from {1}.\n'
|
||||
msg = 'Repo \'{0}\' has been removed from {1}.\n'
|
||||
if count == 1 and os.path.isfile(repo_file):
|
||||
msg = ('File {1} containing repo {0!r} has been '
|
||||
msg = ('File {1} containing repo \'{0}\' has been '
|
||||
'removed.\n')
|
||||
try:
|
||||
os.remove(repo_file)
|
||||
@ -930,7 +939,9 @@ def file_dict(*packages):
|
||||
files = []
|
||||
cmd = cmd_files[:]
|
||||
cmd.append(package)
|
||||
out = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
out = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
for line in out['stdout'].splitlines():
|
||||
if line.startswith('/'):
|
||||
files.append(line)
|
||||
@ -966,8 +977,10 @@ def owner(*paths):
|
||||
cmd_search = ['opkg', 'search']
|
||||
for path in paths:
|
||||
cmd = cmd_search[:]
|
||||
cmd.append(_cmd_quote(path))
|
||||
output = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')
|
||||
cmd.append(path)
|
||||
output = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
if output:
|
||||
ret[path] = output.split(' - ')[0].strip()
|
||||
else:
|
||||
|
@ -12,6 +12,7 @@ import re
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
from salt.exceptions import CommandExecutionError, MinionError
|
||||
|
||||
# Import 3rd-party libs
|
||||
@ -68,10 +69,12 @@ def latest_version(*names, **kwargs):
|
||||
# Initialize the dict with empty strings
|
||||
for name in names:
|
||||
ret[name] = ''
|
||||
cmd = 'pacman -Sp --needed --print-format "%n %v" ' \
|
||||
'{0}'.format(' '.join(names))
|
||||
out = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
cmd = ['pacman', '-Sp', '--needed', '--print-format', '%n %v']
|
||||
cmd.extend(names)
|
||||
out = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
try:
|
||||
name, version_num = line.split()
|
||||
# Only add to return dict if package is in the list of packages
|
||||
@ -123,14 +126,14 @@ def list_upgrades(refresh=False):
|
||||
salt '*' pkg.list_upgrades
|
||||
'''
|
||||
upgrades = {}
|
||||
options = ['-S', '-p', '-u', '--print-format "%n %v"']
|
||||
cmd = ['pacman', '-S', '-p', '-u', '--print-format', '%n %v']
|
||||
|
||||
if refresh:
|
||||
options.append('-y')
|
||||
cmd.append('-y')
|
||||
|
||||
cmd = ('pacman {0}').format(' '.join(options))
|
||||
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
@ -138,13 +141,13 @@ def list_upgrades(refresh=False):
|
||||
comment += call['stderr']
|
||||
if 'stdout' in call:
|
||||
comment += call['stdout']
|
||||
raise CommandExecutionError(
|
||||
'{0}'.format(comment)
|
||||
)
|
||||
if comment:
|
||||
comment = ': ' + comment
|
||||
raise CommandExecutionError('Error listing upgrades' + comment)
|
||||
else:
|
||||
out = call['stdout']
|
||||
|
||||
for line in iter(out.splitlines()):
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
comps = line.split(' ')
|
||||
if len(comps) != 2:
|
||||
continue
|
||||
@ -194,17 +197,17 @@ def list_pkgs(versions_as_list=False, **kwargs):
|
||||
__salt__['pkg_resource.stringify'](ret)
|
||||
return ret
|
||||
|
||||
cmd = 'pacman -Q'
|
||||
cmd = ['pacman', '-Q']
|
||||
ret = {}
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
name, version_num = line.split()[0:2]
|
||||
except ValueError:
|
||||
log.error('Problem parsing pacman -Q: Unexpected formatting in '
|
||||
'line: "{0}"'.format(line))
|
||||
'line: \'{0}\''.format(line))
|
||||
else:
|
||||
__salt__['pkg_resource.add_pkg'](ret, name, version_num)
|
||||
|
||||
@ -227,22 +230,23 @@ def refresh_db():
|
||||
|
||||
salt '*' pkg.refresh_db
|
||||
'''
|
||||
cmd = 'LANG=C pacman -Sy'
|
||||
cmd = ['pacman', '-Sy']
|
||||
ret = {}
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace',
|
||||
python_shell=True)
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
env={'LANG': 'C'},
|
||||
python_shell=False)
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
if 'stderr' in call:
|
||||
comment += call['stderr']
|
||||
|
||||
comment += ': ' + call['stderr']
|
||||
raise CommandExecutionError(
|
||||
'{0}'.format(comment)
|
||||
'Error refreshing package database' + comment
|
||||
)
|
||||
else:
|
||||
out = call['stdout']
|
||||
|
||||
for line in out.splitlines():
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if line.strip().startswith('::'):
|
||||
continue
|
||||
if not line:
|
||||
@ -335,16 +339,14 @@ def install(name=None,
|
||||
version_num = kwargs.get('version')
|
||||
if version_num:
|
||||
if pkgs is None and sources is None:
|
||||
# Allow "version" to work for single package target
|
||||
# Allow 'version' to work for single package target
|
||||
pkg_params = {name: version_num}
|
||||
else:
|
||||
log.warning('"version" parameter will be ignored for multiple '
|
||||
log.warning('\'version\' parameter will be ignored for multiple '
|
||||
'package targets')
|
||||
|
||||
if pkg_type == 'file':
|
||||
cmd = 'pacman -U --noprogressbar --noconfirm ' \
|
||||
'{0}'.format(' '.join(pkg_params))
|
||||
targets = pkg_params
|
||||
cmd = ['pacman', '-U', '--noprogressbar', '--noconfirm'] + pkg_params
|
||||
elif pkg_type == 'repository':
|
||||
targets = []
|
||||
problems = []
|
||||
@ -362,8 +364,8 @@ def install(name=None,
|
||||
prefix = prefix or '='
|
||||
targets.append('{0}{1}{2}'.format(param, prefix, verstr))
|
||||
else:
|
||||
msg = 'Invalid version string "{0}" for package ' \
|
||||
'"{1}"'.format(version_num, name)
|
||||
msg = 'Invalid version string \'{0}\' for package ' \
|
||||
'\'{1}\''.format(version_num, name)
|
||||
problems.append(msg)
|
||||
if problems:
|
||||
for problem in problems:
|
||||
@ -375,10 +377,10 @@ def install(name=None,
|
||||
if salt.utils.is_true(sysupgrade):
|
||||
options.append('-u')
|
||||
|
||||
cmd = 'pacman -S "{0}"'.format('" "'.join(options+targets))
|
||||
cmd = ['pacman', '-S'] + options + targets
|
||||
|
||||
old = list_pkgs()
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -404,14 +406,15 @@ def upgrade(refresh=False):
|
||||
'''
|
||||
ret = {'changes': {},
|
||||
'result': True,
|
||||
'comment': '',
|
||||
}
|
||||
'comment': ''}
|
||||
|
||||
old = list_pkgs()
|
||||
cmd = 'pacman -Su --noprogressbar --noconfirm'
|
||||
cmd = ['pacman', '-Su', '--noprogressbar', '--noconfirm']
|
||||
if salt.utils.is_true(refresh):
|
||||
cmd += ' -y'
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
cmd.append('-y')
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
if call['retcode'] != 0:
|
||||
ret['result'] = False
|
||||
if 'stderr' in call:
|
||||
@ -439,13 +442,11 @@ def _uninstall(action='remove', name=None, pkgs=None, **kwargs):
|
||||
targets = [x for x in pkg_params if x in old]
|
||||
if not targets:
|
||||
return {}
|
||||
remove_arg = '-Rsc' if action == 'purge' else '-R'
|
||||
cmd = (
|
||||
'pacman {0} '
|
||||
'--noprogressbar '
|
||||
'--noconfirm {1}'
|
||||
).format(remove_arg, ' '.join(targets))
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
cmd = ['pacman',
|
||||
'-Rsc' if action == 'purge' else '-R',
|
||||
'--noprogressbar',
|
||||
'--noconfirm'] + targets
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -528,9 +529,10 @@ def file_list(*packages):
|
||||
'''
|
||||
errors = []
|
||||
ret = []
|
||||
cmd = 'pacman -Ql {0}'.format(' '.join(packages))
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
cmd = ['pacman', '-Ql']
|
||||
cmd.extend(packages)
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if line.startswith('error'):
|
||||
errors.append(line)
|
||||
else:
|
||||
@ -555,9 +557,10 @@ def file_dict(*packages):
|
||||
'''
|
||||
errors = []
|
||||
ret = {}
|
||||
cmd = 'pacman -Ql {0}'.format(' '.join(packages))
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
cmd = ['pacman', '-Ql']
|
||||
cmd.extend(packages)
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if line.startswith('error'):
|
||||
errors.append(line)
|
||||
else:
|
||||
@ -588,9 +591,10 @@ def owner(*paths):
|
||||
if not paths:
|
||||
return ''
|
||||
ret = {}
|
||||
cmd = 'pacman -Qqo {0!r}'
|
||||
cmd_prefix = ['pacman', '-Qqo']
|
||||
for path in paths:
|
||||
ret[path] = __salt__['cmd.run_stdout'](cmd.format(path))
|
||||
ret[path] = __salt__['cmd.run_stdout'](cmd_prefix + [path],
|
||||
python_shell=False)
|
||||
if len(ret) == 1:
|
||||
return next(six.itervalues(ret))
|
||||
return ret
|
||||
|
@ -74,11 +74,11 @@ def _pkg(jail=None, chroot=None):
|
||||
Returns the prefix for a pkg command, using -j if a jail is specified, or
|
||||
-c if chroot is specified.
|
||||
'''
|
||||
ret = 'pkg'
|
||||
ret = ['pkg']
|
||||
if jail:
|
||||
ret += ' -j {0!r}'.format(jail)
|
||||
ret.extend(['-j', jail])
|
||||
elif chroot:
|
||||
ret += ' -c {0!r}'.format(chroot)
|
||||
ret.extend(['-c', chroot])
|
||||
return ret
|
||||
|
||||
|
||||
@ -94,7 +94,7 @@ def _get_version(name, results):
|
||||
``pkg search`` will return all packages for which the pattern is a match.
|
||||
Narrow this down and return the package version, or None if no exact match.
|
||||
'''
|
||||
for line in results.splitlines():
|
||||
for line in salt.utils.itertools.split(results, '\n'):
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
@ -228,12 +228,11 @@ def refresh_db(jail=None, chroot=None, force=False):
|
||||
|
||||
salt '*' pkg.refresh_db force=True
|
||||
'''
|
||||
opts = ''
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('update')
|
||||
if force:
|
||||
opts += ' -f'
|
||||
return __salt__['cmd.retcode'](
|
||||
'{0} update{1}'.format(_pkg(jail, chroot), opts),
|
||||
python_shell=False) == 0
|
||||
cmd.append('-f')
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
# Support pkg.update to refresh the db, since this is the CLI usage
|
||||
@ -273,6 +272,7 @@ def latest_version(*names, **kwargs):
|
||||
else:
|
||||
quiet = False
|
||||
|
||||
cmd_prefix = _pkg(jail, chroot) + ['search']
|
||||
for name in names:
|
||||
cmd = [_pkg(jail, chroot), 'search']
|
||||
if quiet:
|
||||
@ -281,7 +281,9 @@ def latest_version(*names, **kwargs):
|
||||
|
||||
pkgver = _get_version(
|
||||
name,
|
||||
__salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd_prefix + [name],
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
)
|
||||
if pkgver is not None:
|
||||
installed = pkgs.get(name, [])
|
||||
@ -360,12 +362,11 @@ def list_pkgs(versions_as_list=False,
|
||||
|
||||
ret = {}
|
||||
origins = {}
|
||||
cmd = '{0} info -ao'.format(_pkg(jail, chroot))
|
||||
out = __salt__['cmd.run_stdout'](
|
||||
cmd,
|
||||
python_shell=False,
|
||||
output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
_pkg(jail, chroot) + ['info', '-ao'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if not line:
|
||||
continue
|
||||
try:
|
||||
@ -467,16 +468,13 @@ def stats(local=False, remote=False, jail=None, chroot=None):
|
||||
opts += 'l'
|
||||
if remote:
|
||||
opts += 'r'
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
|
||||
res = __salt__['cmd.run'](
|
||||
'{0} stats {1}'.format(_pkg(jail, chroot), opts),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
)
|
||||
res = [x.strip("\t") for x in res.split("\n")]
|
||||
return res
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('stats')
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
return [x.strip('\t') for x in salt.utils.itertools.split(out, '\n')]
|
||||
|
||||
|
||||
def backup(file_name, jail=None, chroot=None):
|
||||
@ -512,12 +510,12 @@ def backup(file_name, jail=None, chroot=None):
|
||||
|
||||
salt '*' pkg.backup /tmp/pkg chroot=/path/to/chroot
|
||||
'''
|
||||
res = __salt__['cmd.run'](
|
||||
'{0} backup -d {1!r}'.format(_pkg(jail, chroot), file_name),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
ret = __salt__['cmd.run'](
|
||||
_pkg(jail, chroot) + ['backup', '-d', file_name],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
return res.split('...')[1]
|
||||
return ret.split('...')[1]
|
||||
|
||||
|
||||
def restore(file_name, jail=None, chroot=None):
|
||||
@ -554,9 +552,9 @@ def restore(file_name, jail=None, chroot=None):
|
||||
salt '*' pkg.restore /tmp/pkg chroot=/path/to/chroot
|
||||
'''
|
||||
return __salt__['cmd.run'](
|
||||
'{0} backup -r {1!r}'.format(_pkg(jail, chroot), file_name),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
_pkg(jail, chroot) + ['backup', '-r', file_name],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -590,9 +588,9 @@ def audit(jail=None, chroot=None):
|
||||
salt '*' pkg.audit chroot=/path/to/chroot
|
||||
'''
|
||||
return __salt__['cmd.run'](
|
||||
'{0} audit -F'.format(_pkg(jail, chroot)),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
_pkg(jail, chroot) + ['audit', '-F'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -743,7 +741,6 @@ def install(name=None,
|
||||
return {}
|
||||
|
||||
opts = ''
|
||||
repo_opts = ''
|
||||
if salt.utils.is_true(orphan):
|
||||
opts += 'A'
|
||||
if salt.utils.is_true(force):
|
||||
@ -760,16 +757,10 @@ def install(name=None,
|
||||
opts += 'q'
|
||||
if salt.utils.is_true(reinstall_requires):
|
||||
opts += 'R'
|
||||
if fromrepo:
|
||||
repo_opts += 'r {0}'.format(fromrepo)
|
||||
if salt.utils.is_true(regex):
|
||||
opts += 'x'
|
||||
if salt.utils.is_true(pcre):
|
||||
opts += 'X'
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
if repo_opts:
|
||||
repo_opts = '-' + repo_opts
|
||||
|
||||
old = list_pkgs(jail=jail, chroot=chroot)
|
||||
|
||||
@ -791,15 +782,19 @@ def install(name=None,
|
||||
else:
|
||||
targets.append('{0}-{1}'.format(param, version_num))
|
||||
|
||||
cmd = '{0} {1} {2} {3} {4}'.format(
|
||||
_pkg(jail, chroot), pkg_cmd, repo_opts, opts, ' '.join(targets)
|
||||
)
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append(pkg_cmd)
|
||||
if fromrepo:
|
||||
cmd.extend(['-r', fromrepo])
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
cmd.extend(targets)
|
||||
|
||||
if pkg_cmd == 'add' and salt.utils.is_true(dryrun):
|
||||
# pkg add doesn't have a dryrun mode, so echo out what will be run
|
||||
return cmd
|
||||
return ' '.join(cmd)
|
||||
|
||||
__salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop(_contextkey(jail, chroot), None)
|
||||
__context__.pop(_contextkey(jail, chroot, prefix='pkg.origin'), None)
|
||||
new = list_pkgs(jail=jail, chroot=chroot)
|
||||
@ -944,13 +939,13 @@ def remove(name=None,
|
||||
opts += 'x'
|
||||
if salt.utils.is_true(pcre):
|
||||
opts += 'X'
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
|
||||
cmd = '{0} delete {1} {2}'.format(
|
||||
_pkg(jail, chroot), opts, ' '.join(targets)
|
||||
)
|
||||
__salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('delete')
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
cmd.extend(targets)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop(_contextkey(jail, chroot), None)
|
||||
__context__.pop(_contextkey(jail, chroot, prefix='pkg.origin'), None)
|
||||
new = list_pkgs(jail=jail, chroot=chroot, with_origin=True)
|
||||
@ -1048,11 +1043,17 @@ def upgrade(*names, **kwargs):
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('upgrade')
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
cmd.extend(names)
|
||||
|
||||
old = list_pkgs()
|
||||
call = __salt__['cmd.run_all'](
|
||||
'{0} upgrade {1} {2}'.format(_pkg(jail, chroot), opts, ' '.join(names)),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
if call['retcode'] != 0:
|
||||
ret['result'] = False
|
||||
@ -1080,9 +1081,9 @@ def clean(jail=None, chroot=None):
|
||||
salt '*' pkg.clean chroot=/path/to/chroot
|
||||
'''
|
||||
return __salt__['cmd.run'](
|
||||
'{0} clean'.format(_pkg(jail, chroot)),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
_pkg(jail, chroot) + ['clean'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -1109,12 +1110,15 @@ def autoremove(jail=None, chroot=None, dryrun=False):
|
||||
opts += 'n'
|
||||
else:
|
||||
opts += 'y'
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('autoremove')
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
cmd.append('-' + opts)
|
||||
return __salt__['cmd.run'](
|
||||
'{0} autoremove {1}'.format(_pkg(jail, chroot), opts),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -1185,13 +1189,15 @@ def check(jail=None,
|
||||
opts += 'r'
|
||||
if checksum:
|
||||
opts += 's'
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('check')
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
return __salt__['cmd.run'](
|
||||
'{0} check {1}'.format(_pkg(jail, chroot), opts),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -1248,12 +1254,16 @@ def which(path, jail=None, chroot=None, origin=False, quiet=False):
|
||||
opts += 'q'
|
||||
if origin:
|
||||
opts += 'o'
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('which')
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
cmd.append('-' + opts)
|
||||
cmd.append(path)
|
||||
return __salt__['cmd.run'](
|
||||
'{0} which {1} {2}'.format(_pkg(jail, chroot), opts, path),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -1435,13 +1445,16 @@ def search(name,
|
||||
opts += 'o'
|
||||
if prefix:
|
||||
opts += 'p'
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('search')
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
cmd.append(name)
|
||||
return __salt__['cmd.run'](
|
||||
'{0} search {1} {2}'.format(_pkg(jail, chroot), opts, name),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -1559,13 +1572,10 @@ def fetch(name,
|
||||
salt '*' pkg.fetch <package name> depends=True
|
||||
'''
|
||||
opts = ''
|
||||
repo_opts = ''
|
||||
if fetch_all:
|
||||
opts += 'a'
|
||||
if quiet:
|
||||
opts += 'q'
|
||||
if fromrepo:
|
||||
repo_opts += 'r {0}'.format(fromrepo)
|
||||
if glob:
|
||||
opts += 'g'
|
||||
if regex:
|
||||
@ -1576,17 +1586,18 @@ def fetch(name,
|
||||
opts += 'L'
|
||||
if depends:
|
||||
opts += 'd'
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
if repo_opts:
|
||||
repo_opts = '-' + repo_opts
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.extend(['fetch', '-y'])
|
||||
if fromrepo:
|
||||
cmd.extend(['-r', fromrepo])
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
cmd.append(name)
|
||||
return __salt__['cmd.run'](
|
||||
'{0} fetch -y {1} {2} {3}'.format(
|
||||
_pkg(jail, chroot), opts, repo_opts, name
|
||||
),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
@ -1647,11 +1658,14 @@ def updating(name,
|
||||
opts += 'd {0}'.format(filedate)
|
||||
if filename:
|
||||
opts += 'f {0}'.format(filename)
|
||||
if opts:
|
||||
opts = '-' + opts
|
||||
|
||||
cmd = _pkg(jail, chroot)
|
||||
cmd.append('updating')
|
||||
if opts:
|
||||
cmd.append('-' + opts)
|
||||
cmd.append(name)
|
||||
return __salt__['cmd.run'](
|
||||
'{0} updating {1} {2}'.format(_pkg(jail, chroot), opts, name),
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
|
@ -33,14 +33,14 @@ import hashlib
|
||||
import os
|
||||
import tempfile
|
||||
try:
|
||||
import pipes
|
||||
import csv
|
||||
HAS_ALL_IMPORTS = True
|
||||
HAS_CSV = True
|
||||
except ImportError:
|
||||
HAS_ALL_IMPORTS = False
|
||||
HAS_CSV = False
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
|
||||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
@ -68,7 +68,7 @@ def __virtual__():
|
||||
'''
|
||||
Only load this module if the psql bin exists
|
||||
'''
|
||||
if all((salt.utils.which('psql'), HAS_ALL_IMPORTS)):
|
||||
if all((salt.utils.which('psql'), HAS_CSV)):
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -146,7 +146,8 @@ def version(user=None, host=None, port=None, maintenance_db=None,
|
||||
ret = _run_psql(
|
||||
cmd, runas=runas, password=password, host=host, port=port, user=user)
|
||||
|
||||
for line in ret['stdout'].splitlines():
|
||||
for line in salt.utils.itertools.split(ret['stdout'], '\n'):
|
||||
# Just return the first line
|
||||
return line
|
||||
|
||||
|
||||
@ -221,10 +222,9 @@ def _psql_cmd(*args, **kwargs):
|
||||
cmd += ['--port', str(port)]
|
||||
if not maintenance_db:
|
||||
maintenance_db = 'postgres'
|
||||
cmd += ['--dbname', maintenance_db]
|
||||
cmd += args
|
||||
cmdstr = ' '.join([pipes.quote(c) for c in cmd])
|
||||
return cmdstr
|
||||
cmd.extend(['--dbname', maintenance_db])
|
||||
cmd.extend(args)
|
||||
return cmd
|
||||
|
||||
|
||||
def _psql_prepare_and_run(cmd,
|
||||
@ -377,9 +377,9 @@ def db_create(name,
|
||||
# doesn't get thrown by dashes in the name
|
||||
'OWNER': owner and '"{0}"'.format(owner),
|
||||
'TEMPLATE': template,
|
||||
'ENCODING': encoding and '{0!r}'.format(encoding),
|
||||
'LC_COLLATE': lc_collate and '{0!r}'.format(lc_collate),
|
||||
'LC_CTYPE': lc_ctype and '{0!r}'.format(lc_ctype),
|
||||
'ENCODING': encoding and '\'{0}\''.format(encoding),
|
||||
'LC_COLLATE': lc_collate and '\'{0}\''.format(lc_collate),
|
||||
'LC_CTYPE': lc_ctype and '\'{0}\''.format(lc_ctype),
|
||||
'TABLESPACE': tablespace,
|
||||
})
|
||||
with_chunks = []
|
||||
@ -878,7 +878,7 @@ def _role_cmd_args(name,
|
||||
):
|
||||
skip_passwd = True
|
||||
if isinstance(rolepassword, six.string_types) and bool(rolepassword):
|
||||
escaped_password = '{0!r}'.format(
|
||||
escaped_password = '\'{0}\''.format(
|
||||
_maybe_encrypt_password(name,
|
||||
rolepassword.replace('\'', '\'\''),
|
||||
encrypted=encrypted))
|
||||
@ -943,7 +943,7 @@ def _role_create(name,
|
||||
# check if role exists
|
||||
if user_exists(name, user, host, port, maintenance_db,
|
||||
password=password, runas=runas):
|
||||
log.info('{0} {1!r} already exists'.format(typ_.capitalize(), name))
|
||||
log.info('{0} \'{1}\' already exists'.format(typ_.capitalize(), name))
|
||||
return False
|
||||
|
||||
sub_cmd = 'CREATE ROLE "{0}" WITH'.format(name)
|
||||
@ -1053,7 +1053,9 @@ def _role_update(name,
|
||||
|
||||
# check if user exists
|
||||
if not bool(role):
|
||||
log.info('{0} {1!r} could not be found'.format(typ_.capitalize(), name))
|
||||
log.info(
|
||||
'{0} \'{1}\' could not be found'.format(typ_.capitalize(), name)
|
||||
)
|
||||
return False
|
||||
|
||||
sub_cmd = 'ALTER ROLE "{0}" WITH'.format(name)
|
||||
@ -1139,7 +1141,7 @@ def _role_remove(name, user=None, host=None, port=None, maintenance_db=None,
|
||||
# check if user exists
|
||||
if not user_exists(name, user, host, port, maintenance_db,
|
||||
password=password, runas=runas):
|
||||
log.info('User {0!r} does not exist'.format(name))
|
||||
log.info('User \'{0}\' does not exist'.format(name))
|
||||
return False
|
||||
|
||||
# user exists, proceed
|
||||
@ -1153,7 +1155,7 @@ def _role_remove(name, user=None, host=None, port=None, maintenance_db=None,
|
||||
password=password, runas=runas):
|
||||
return True
|
||||
else:
|
||||
log.info('Failed to delete user {0!r}.'.format(name))
|
||||
log.info('Failed to delete user \'{0}\'.'.format(name))
|
||||
return False
|
||||
|
||||
|
||||
@ -1779,7 +1781,7 @@ def schema_create(dbname, name, owner=None,
|
||||
if schema_exists(dbname, name,
|
||||
db_user=db_user, db_password=db_password,
|
||||
db_host=db_host, db_port=db_port):
|
||||
log.info('{0!r} already exists in {1!r}'.format(name, dbname))
|
||||
log.info('\'{0}\' already exists in \'{1}\''.format(name, dbname))
|
||||
return False
|
||||
|
||||
sub_cmd = 'CREATE SCHEMA {0}'.format(name)
|
||||
@ -1834,7 +1836,7 @@ def schema_remove(dbname, name,
|
||||
if not schema_exists(dbname, name,
|
||||
db_user=db_user, db_password=db_password,
|
||||
db_host=db_host, db_port=db_port):
|
||||
log.info('Schema {0!r} does not exist in {1!r}'.format(name, dbname))
|
||||
log.info('Schema \'{0}\' does not exist in \'{1}\''.format(name, dbname))
|
||||
return False
|
||||
|
||||
# schema exists, proceed
|
||||
@ -1850,7 +1852,7 @@ def schema_remove(dbname, name,
|
||||
db_host=db_host, db_port=db_port):
|
||||
return True
|
||||
else:
|
||||
log.info('Failed to delete schema {0!r}.'.format(name))
|
||||
log.info('Failed to delete schema \'{0}\'.'.format(name))
|
||||
return False
|
||||
|
||||
|
||||
|
@ -75,7 +75,7 @@ def _publish(
|
||||
|
||||
arg = _parse_args(arg)
|
||||
|
||||
log.info('Publishing {0!r} to {master_uri}'.format(fun, **__opts__))
|
||||
log.info('Publishing \'{0}\' to {master_uri}'.format(fun, **__opts__))
|
||||
auth = salt.crypt.SAuth(__opts__)
|
||||
tok = auth.gen_token('salt')
|
||||
load = {'cmd': 'minion_pub',
|
||||
@ -93,7 +93,7 @@ def _publish(
|
||||
try:
|
||||
peer_data = channel.send(load)
|
||||
except SaltReqTimeoutError:
|
||||
return '{0!r} publish timed out'.format(fun)
|
||||
return '\'{0}\' publish timed out'.format(fun)
|
||||
if not peer_data:
|
||||
return {}
|
||||
# CLI args are passed as strings, re-cast to keep time.sleep happy
|
||||
@ -263,7 +263,7 @@ def runner(fun, arg=None, timeout=5):
|
||||
|
||||
if 'master_uri' not in __opts__:
|
||||
return 'No access to master. If using salt-call with --local, please remove.'
|
||||
log.info('Publishing runner {0!r} to {master_uri}'.format(fun, **__opts__))
|
||||
log.info('Publishing runner \'{0}\' to {master_uri}'.format(fun, **__opts__))
|
||||
auth = salt.crypt.SAuth(__opts__)
|
||||
tok = auth.gen_token('salt')
|
||||
load = {'cmd': 'minion_runner',
|
||||
@ -277,4 +277,4 @@ def runner(fun, arg=None, timeout=5):
|
||||
try:
|
||||
return channel.send(load)
|
||||
except SaltReqTimeoutError:
|
||||
return '{0!r} runner publish timed out'.format(fun)
|
||||
return '\'{0}\' runner publish timed out'.format(fun)
|
||||
|
@ -63,7 +63,12 @@ def _get_gecos(name):
|
||||
'''
|
||||
Retrieve GECOS field info and return it in dictionary form
|
||||
'''
|
||||
try:
|
||||
gecos_field = pwd.getpwnam(name).pw_gecos.split(',', 3)
|
||||
except KeyError:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if not gecos_field:
|
||||
return {}
|
||||
else:
|
||||
@ -87,6 +92,25 @@ def _build_gecos(gecos_dict):
|
||||
gecos_dict.get('homephone', ''))
|
||||
|
||||
|
||||
def _update_gecos(name, key, value):
|
||||
'''
|
||||
Common code to change a user's GECOS information
|
||||
'''
|
||||
if not isinstance(value, six.string_types):
|
||||
value = str(value)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if value == pre_info[key]:
|
||||
return True
|
||||
gecos_data = copy.deepcopy(pre_info)
|
||||
gecos_data[key] = value
|
||||
cmd = ['pw', 'usermod', name, '-c', _build_gecos(gecos_data)]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
return _get_gecos(name).get(key) == value
|
||||
|
||||
|
||||
def add(name,
|
||||
uid=None,
|
||||
gid=None,
|
||||
@ -118,32 +142,30 @@ def add(name,
|
||||
|
||||
if isinstance(groups, six.string_types):
|
||||
groups = groups.split(',')
|
||||
cmd = 'pw useradd '
|
||||
cmd = ['pw', 'useradd']
|
||||
if uid:
|
||||
cmd += '-u {0} '.format(uid)
|
||||
cmd.extend(['-u', uid])
|
||||
if gid:
|
||||
cmd += '-g {0} '.format(gid)
|
||||
cmd.extend(['-g', gid])
|
||||
if groups:
|
||||
cmd += '-G {0} '.format(','.join(groups))
|
||||
cmd.extend(['-G', ','.join(groups)])
|
||||
if home is not None:
|
||||
cmd += '-d {0} '.format(home)
|
||||
cmd.extend(['-d', home])
|
||||
if createhome is True:
|
||||
cmd += '-m '
|
||||
cmd.append('-m')
|
||||
if loginclass:
|
||||
cmd += '-L {0}'.format(loginclass)
|
||||
cmd.extend(['-L', loginclass])
|
||||
if shell:
|
||||
cmd += '-s {0} '.format(shell)
|
||||
cmd.extend(['-s', shell])
|
||||
if not salt.utils.is_true(unique):
|
||||
cmd += '-o '
|
||||
gecos_field = '{0},{1},{2},{3}'.format(fullname,
|
||||
roomnumber,
|
||||
workphone,
|
||||
homephone)
|
||||
cmd += '-c "{0}" '.format(gecos_field)
|
||||
cmd += '-n {0}'.format(name)
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
return not ret['retcode']
|
||||
cmd.append('-o')
|
||||
gecos_field = _build_gecos({'fullname': fullname,
|
||||
'roomnumber': roomnumber,
|
||||
'workphone': workphone,
|
||||
'homephone': homephone})
|
||||
cmd.extend(['-c', gecos_field])
|
||||
cmd.extend(['-n', name])
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def delete(name, remove=False, force=False):
|
||||
@ -159,14 +181,11 @@ def delete(name, remove=False, force=False):
|
||||
if salt.utils.is_true(force):
|
||||
log.error('pw userdel does not support force-deleting user while '
|
||||
'user is logged in')
|
||||
cmd = 'pw userdel '
|
||||
cmd = ['pw', 'userdel']
|
||||
if remove:
|
||||
cmd += '-r '
|
||||
cmd += '-n ' + name
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
return not ret['retcode']
|
||||
cmd.append('-r')
|
||||
cmd.extend(['-n', name])
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def getent(refresh=False):
|
||||
@ -200,14 +219,15 @@ def chuid(name, uid):
|
||||
salt '*' user.chuid foo 4376
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if uid == pre_info['uid']:
|
||||
return True
|
||||
cmd = 'pw usermod -u {0} -n {1}'.format(uid, name)
|
||||
cmd = ['pw', 'usermod', '-u', uid, '-n', name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['uid'] != pre_info['uid']:
|
||||
return post_info['uid'] == uid
|
||||
return False
|
||||
return info(name).get('uid') == uid
|
||||
|
||||
|
||||
def chgid(name, gid):
|
||||
@ -221,14 +241,15 @@ def chgid(name, gid):
|
||||
salt '*' user.chgid foo 4376
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if gid == pre_info['gid']:
|
||||
return True
|
||||
cmd = 'pw usermod -g {0} -n {1}'.format(gid, name)
|
||||
cmd = ['pw', 'usermod', '-g', gid, '-n', name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['gid'] != pre_info['gid']:
|
||||
return post_info['gid'] == gid
|
||||
return False
|
||||
return info(name).get('gid') == gid
|
||||
|
||||
|
||||
def chshell(name, shell):
|
||||
@ -242,20 +263,31 @@ def chshell(name, shell):
|
||||
salt '*' user.chshell foo /bin/zsh
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if shell == pre_info['shell']:
|
||||
return True
|
||||
cmd = 'pw usermod -s {0} -n {1}'.format(shell, name)
|
||||
cmd = ['pw', 'usermod', '-s', shell, '-n', name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['shell'] != pre_info['shell']:
|
||||
return post_info['shell'] == shell
|
||||
return False
|
||||
return info(name).get('shell') == shell
|
||||
|
||||
|
||||
def chhome(name, home, persist=False):
|
||||
'''
|
||||
Change the home directory of the user, pass true for persist to copy files
|
||||
to the new home dir
|
||||
Set a new home directory for an existing user
|
||||
|
||||
name
|
||||
Username to modify
|
||||
|
||||
home
|
||||
New home directory to set
|
||||
|
||||
persist : False
|
||||
Set to ``True`` to prevent configuration files in the new home
|
||||
directory from being overwritten by the files from the skeleton
|
||||
directory.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -264,22 +296,34 @@ def chhome(name, home, persist=False):
|
||||
salt '*' user.chhome foo /home/users/foo True
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if home == pre_info['home']:
|
||||
return True
|
||||
cmd = 'pw usermod {0} -d {1}'.format(name, home)
|
||||
cmd = ['pw', 'usermod', name, '-d', home]
|
||||
if persist:
|
||||
cmd += ' -m '
|
||||
cmd.append('-m')
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['home'] != pre_info['home']:
|
||||
return post_info['home'] == home
|
||||
return False
|
||||
return info(name).get('home') == home
|
||||
|
||||
|
||||
def chgroups(name, groups, append=False):
|
||||
'''
|
||||
Change the groups this user belongs to, add append to append the specified
|
||||
Change the groups to which a user belongs
|
||||
|
||||
name
|
||||
Username to modify
|
||||
|
||||
groups
|
||||
List of groups to set for the user. Can be passed as a comma-separated
|
||||
list or a Python list.
|
||||
|
||||
append : False
|
||||
Set to ``True`` to append these groups to the user's existing list of
|
||||
groups. Otherwise, the specified groups will replace any existing
|
||||
groups for the user.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -294,8 +338,8 @@ def chgroups(name, groups, append=False):
|
||||
return True
|
||||
if append:
|
||||
groups += ugrps
|
||||
cmd = 'pw usermod -G {0} -n {1}'.format(','.join(groups), name)
|
||||
return not __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
cmd = ['pw', 'usermod', '-G', ','.join(groups), '-n', name]
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def chfullname(name, fullname):
|
||||
@ -308,20 +352,7 @@ def chfullname(name, fullname):
|
||||
|
||||
salt '*' user.chfullname foo "Foo Bar"
|
||||
'''
|
||||
fullname = str(fullname)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if fullname == pre_info['fullname']:
|
||||
return True
|
||||
gecos_field = copy.deepcopy(pre_info)
|
||||
gecos_field['fullname'] = fullname
|
||||
cmd = 'pw usermod {0} -c "{1}"'.format(name, _build_gecos(gecos_field))
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['fullname'] != pre_info['fullname']:
|
||||
return post_info['fullname'] == fullname
|
||||
return False
|
||||
return _update_gecos(name, 'fullname', fullname)
|
||||
|
||||
|
||||
def chroomnumber(name, roomnumber):
|
||||
@ -334,20 +365,7 @@ def chroomnumber(name, roomnumber):
|
||||
|
||||
salt '*' user.chroomnumber foo 123
|
||||
'''
|
||||
roomnumber = str(roomnumber)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if roomnumber == pre_info['roomnumber']:
|
||||
return True
|
||||
gecos_field = copy.deepcopy(pre_info)
|
||||
gecos_field['roomnumber'] = roomnumber
|
||||
cmd = 'pw usermod {0} -c "{1}"'.format(name, _build_gecos(gecos_field))
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['roomnumber'] != pre_info['roomnumber']:
|
||||
return post_info['roomnumber'] == roomnumber
|
||||
return False
|
||||
return _update_gecos(name, 'roomnumber', roomnumber)
|
||||
|
||||
|
||||
def chworkphone(name, workphone):
|
||||
@ -360,20 +378,7 @@ def chworkphone(name, workphone):
|
||||
|
||||
salt '*' user.chworkphone foo "7735550123"
|
||||
'''
|
||||
workphone = str(workphone)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if workphone == pre_info['workphone']:
|
||||
return True
|
||||
gecos_field = copy.deepcopy(pre_info)
|
||||
gecos_field['workphone'] = workphone
|
||||
cmd = 'pw usermod {0} -c "{1}"'.format(name, _build_gecos(gecos_field))
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['workphone'] != pre_info['workphone']:
|
||||
return post_info['workphone'] == workphone
|
||||
return False
|
||||
return _update_gecos(name, 'workphone', workphone)
|
||||
|
||||
|
||||
def chhomephone(name, homephone):
|
||||
@ -386,20 +391,7 @@ def chhomephone(name, homephone):
|
||||
|
||||
salt '*' user.chhomephone foo "7735551234"
|
||||
'''
|
||||
homephone = str(homephone)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if homephone == pre_info['homephone']:
|
||||
return True
|
||||
gecos_field = copy.deepcopy(pre_info)
|
||||
gecos_field['homephone'] = homephone
|
||||
cmd = 'pw usermod {0} -c "{1}"'.format(name, _build_gecos(gecos_field))
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['homephone'] != pre_info['homephone']:
|
||||
return post_info['homephone'] == homephone
|
||||
return False
|
||||
return _update_gecos(name, 'homephone', homephone)
|
||||
|
||||
|
||||
def info(name):
|
||||
@ -494,11 +486,13 @@ def rename(name, new_name):
|
||||
'''
|
||||
current_info = info(name)
|
||||
if not current_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
new_info = info(new_name)
|
||||
if new_info:
|
||||
raise CommandExecutionError('User {0!r} already exists'.format(new_name))
|
||||
cmd = 'pw usermod -l {0} -n {1}'.format(new_name, name)
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' already exists'.format(new_name)
|
||||
)
|
||||
cmd = ['pw', 'usermod', '-l', new_name, '-n', name]
|
||||
__salt__['cmd.run'](cmd)
|
||||
post_info = info(new_name)
|
||||
if post_info['name'] != current_info['name']:
|
||||
|
@ -6,13 +6,17 @@ data.
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
# Import python libs
|
||||
import json
|
||||
import logging
|
||||
import random
|
||||
import string
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
import salt.ext.six as six
|
||||
from salt.exceptions import SaltInvocationError
|
||||
from salt.ext.six.moves import range
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -108,8 +112,10 @@ def list_users(runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl list_users',
|
||||
runas=runas)
|
||||
res = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'list_users'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
# func to get tags from string such as "[admin, monitoring]"
|
||||
func = lambda string: set(string[1:-1].split(','))
|
||||
@ -128,8 +134,10 @@ def list_vhosts(runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl list_vhosts',
|
||||
runas=runas)
|
||||
res = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'list_vhosts'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
# remove first and last line: Listing ... - ...done
|
||||
return _strip_listing_to_done(res.splitlines())
|
||||
@ -189,10 +197,10 @@ def add_user(name, password=None, runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl add_user {0} {1!r}'.format(name, password),
|
||||
['rabbitmqctl', 'add_user', name, password],
|
||||
output_loglevel='quiet',
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
if clear_pw:
|
||||
# Now, Clear the random password from the account, if necessary
|
||||
@ -221,7 +229,8 @@ def delete_user(name, runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl delete_user {0}'.format(name),
|
||||
res = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'delete_user', name],
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
msg = 'Deleted'
|
||||
@ -242,10 +251,10 @@ def change_password(name, password, runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl change_password {0} {1!r}'.format(name, password),
|
||||
['rabbitmqctl', 'change_password', name, password],
|
||||
runas=runas,
|
||||
output_loglevel='quiet',
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
python_shell=False)
|
||||
msg = 'Password Changed'
|
||||
|
||||
return _format_response(res, msg)
|
||||
@ -263,9 +272,10 @@ def clear_password(name, runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl clear_password {0}'.format(name),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
res = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'clear_password', name],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
msg = 'Password Cleared'
|
||||
|
||||
return _format_response(res, msg)
|
||||
@ -283,9 +293,10 @@ def add_vhost(vhost, runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl add_vhost {0}'.format(vhost),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
res = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'add_vhost', vhost],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
msg = 'Added'
|
||||
return _format_response(res, msg)
|
||||
@ -303,9 +314,10 @@ def delete_vhost(vhost, runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl delete_vhost {0}'.format(vhost),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
res = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'delete_vhost', vhost],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
msg = 'Deleted'
|
||||
return _format_response(res, msg)
|
||||
|
||||
@ -323,10 +335,10 @@ def set_permissions(vhost, user, conf='.*', write='.*', read='.*', runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl set_permissions -p {0} {1} "{2}" "{3}" "{4}"'.format(
|
||||
vhost, user, conf, write, read),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
['rabbitmqctl', 'set_permissions', '-p',
|
||||
vhost, user, conf, write, read],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
msg = 'Permissions Set'
|
||||
return _format_response(res, msg)
|
||||
|
||||
@ -344,9 +356,9 @@ def list_permissions(vhost, runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl list_permissions -p {0}'.format(vhost),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
['rabbitmqctl', 'list_permissions', '-p', vhost],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
return _output_to_dict(res)
|
||||
|
||||
@ -364,9 +376,9 @@ def list_user_permissions(name, runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl list_user_permissions {0}'.format(name),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
['rabbitmqctl', 'list_user_permissions', name],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
return _output_to_dict(res)
|
||||
|
||||
@ -387,9 +399,9 @@ def set_user_tags(name, tags, runas=None):
|
||||
tags = ' '.join(tags)
|
||||
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl set_user_tags {0} {1}'.format(name, tags),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
['rabbitmqctl', 'set_user_tags', name, tags],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
msg = "Tag(s) set"
|
||||
return _format_response(res, msg)
|
||||
|
||||
@ -407,9 +419,9 @@ def status(runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl status',
|
||||
runas=runas
|
||||
)
|
||||
['rabbitmqctl', 'status'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
return res
|
||||
|
||||
|
||||
@ -426,8 +438,9 @@ def cluster_status(runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl cluster_status',
|
||||
runas=runas)
|
||||
['rabbitmqctl', 'cluster_status'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
return res
|
||||
|
||||
@ -442,10 +455,10 @@ def join_cluster(host, user='rabbit', ram_node=None, runas=None):
|
||||
|
||||
salt '*' rabbitmq.join_cluster 'rabbit.example.com' 'rabbit'
|
||||
'''
|
||||
cmd = ['rabbitmqctl', 'join_cluster']
|
||||
if ram_node:
|
||||
cmd = 'rabbitmqctl join_cluster --ram {0}@{1}'.format(user, host)
|
||||
else:
|
||||
cmd = 'rabbitmqctl join_cluster {0}@{1}'.format(user, host)
|
||||
cmd.append('--ram')
|
||||
cmd.append('{0}@{1}'.format(user, host))
|
||||
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
@ -468,11 +481,10 @@ def stop_app(runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl stop_app',
|
||||
runas=runas)
|
||||
|
||||
return res
|
||||
return __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'stop_app'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
|
||||
def start_app(runas=None):
|
||||
@ -487,11 +499,10 @@ def start_app(runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl start_app',
|
||||
runas=runas)
|
||||
|
||||
return res
|
||||
return __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'start_app'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
|
||||
def reset(runas=None):
|
||||
@ -506,11 +517,10 @@ def reset(runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl reset',
|
||||
runas=runas)
|
||||
|
||||
return res
|
||||
return __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'reset'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
|
||||
def force_reset(runas=None):
|
||||
@ -525,14 +535,13 @@ def force_reset(runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl force_reset',
|
||||
runas=runas)
|
||||
|
||||
return res
|
||||
return __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'force_reset'],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
|
||||
|
||||
def list_queues(runas=None, *kwargs):
|
||||
def list_queues(runas=None, *args):
|
||||
'''
|
||||
Returns queue details of the / virtual host
|
||||
|
||||
@ -544,15 +553,12 @@ def list_queues(runas=None, *kwargs):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl list_queues {0}'.format(' '.join(list(kwargs))),
|
||||
python_shell=False,
|
||||
runas=runas,
|
||||
)
|
||||
return res
|
||||
cmd = ['rabbitmqctl', 'list_queues']
|
||||
cmd.extend(args)
|
||||
return __salt__['cmd.run'](cmd, runas=runas, python_shell=False)
|
||||
|
||||
|
||||
def list_queues_vhost(vhost, runas=None, *kwargs):
|
||||
def list_queues_vhost(vhost, runas=None, *args):
|
||||
'''
|
||||
Returns queue details of specified virtual host. This command will consider
|
||||
first parameter as the vhost name and rest will be treated as
|
||||
@ -567,15 +573,9 @@ def list_queues_vhost(vhost, runas=None, *kwargs):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl list_queues -p {0} {1}'.format(
|
||||
vhost,
|
||||
' '.join(list(kwargs))
|
||||
),
|
||||
python_shell=False,
|
||||
runas=runas,
|
||||
)
|
||||
return res
|
||||
cmd = ['rabbitmqctl', 'list_queues', '-p', vhost]
|
||||
cmd.extend(args)
|
||||
return __salt__['cmd.run'](cmd, runas=runas, python_shell=False)
|
||||
|
||||
|
||||
def list_policies(vhost="/", runas=None):
|
||||
@ -594,11 +594,12 @@ def list_policies(vhost="/", runas=None):
|
||||
ret = {}
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run']('rabbitmqctl list_policies -p {0}'.format(
|
||||
vhost),
|
||||
runas=runas)
|
||||
for line in res.splitlines():
|
||||
if '...' not in line and line != '\n':
|
||||
output = __salt__['cmd.run'](
|
||||
['rabbitmqctl', 'list_policies', '-p', vhost],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
for line in salt.utils.itertools.split(output, '\n'):
|
||||
if '...' not in line:
|
||||
parts = line.split('\t')
|
||||
if len(parts) not in (5, 6):
|
||||
continue
|
||||
@ -606,7 +607,8 @@ def list_policies(vhost="/", runas=None):
|
||||
if vhost not in ret:
|
||||
ret[vhost] = {}
|
||||
ret[vhost][name] = {}
|
||||
# How many fields are there? - 'apply_to' was inserted in position 2 at somepoint
|
||||
# How many fields are there? - 'apply_to' was inserted in position
|
||||
# 2 at some point
|
||||
offset = len(parts) - 5
|
||||
if len(parts) == 6:
|
||||
ret[vhost][name]['apply_to'] = parts[2]
|
||||
@ -633,16 +635,17 @@ def set_policy(vhost, name, pattern, definition, priority=None, runas=None):
|
||||
'''
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
"rabbitmqctl set_policy -p {0}{1}{2} {3} '{4}' '{5}'".format(
|
||||
vhost,
|
||||
' --priority ' if priority else '',
|
||||
priority if priority else '',
|
||||
name,
|
||||
pattern,
|
||||
definition.replace("'", '"')),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
if isinstance(definition, dict):
|
||||
definition = json.dumps(definition)
|
||||
if not isinstance(definition, six.string_types):
|
||||
raise SaltInvocationError(
|
||||
'The \'definition\' argument must be a dictionary or JSON string'
|
||||
)
|
||||
cmd = ['rabbitmqctl', 'set_policy', '-p', vhost]
|
||||
if priority:
|
||||
cmd.extend(['--priority', priority])
|
||||
cmd.extend([name, pattern, definition])
|
||||
res = __salt__['cmd.run'](cmd, runas=runas, python_shell=False)
|
||||
log.debug('Set policy: {0}'.format(res))
|
||||
return _format_response(res, 'Set')
|
||||
|
||||
@ -662,10 +665,9 @@ def delete_policy(vhost, name, runas=None):
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
res = __salt__['cmd.run'](
|
||||
'rabbitmqctl clear_policy -p {0} {1}'.format(
|
||||
vhost, name),
|
||||
python_shell=False,
|
||||
runas=runas)
|
||||
['rabbitmqctl', 'clear_policy', '-p', vhost, name],
|
||||
runas=runas,
|
||||
python_shell=False)
|
||||
log.debug('Delete policy: {0}'.format(res))
|
||||
return _format_response(res, 'Deleted')
|
||||
|
||||
@ -698,11 +700,10 @@ def plugin_is_enabled(name, runas=None):
|
||||
|
||||
salt '*' rabbitmq.plugin_is_enabled foo
|
||||
'''
|
||||
rabbitmq = _get_rabbitmq_plugin()
|
||||
cmd = '{0} list -m -e'.format(rabbitmq)
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
ret = __salt__['cmd.run'](cmd, python_shell=False, runas=runas)
|
||||
cmd = [_get_rabbitmq_plugin(), 'list', '-m', '-e']
|
||||
ret = __salt__['cmd.run'](cmd, runas=runas, python_shell=False)
|
||||
return bool(name in ret)
|
||||
|
||||
|
||||
@ -716,13 +717,10 @@ def enable_plugin(name, runas=None):
|
||||
|
||||
salt '*' rabbitmq.enable_plugin foo
|
||||
'''
|
||||
rabbitmq = _get_rabbitmq_plugin()
|
||||
cmd = '{0} enable {1}'.format(rabbitmq, name)
|
||||
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False, runas=runas)
|
||||
|
||||
cmd = [_get_rabbitmq_plugin(), 'enable', name]
|
||||
ret = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
|
||||
return _format_response(ret, 'Enabled')
|
||||
|
||||
|
||||
@ -736,12 +734,8 @@ def disable_plugin(name, runas=None):
|
||||
|
||||
salt '*' rabbitmq.disable_plugin foo
|
||||
'''
|
||||
|
||||
rabbitmq = _get_rabbitmq_plugin()
|
||||
cmd = '{0} disable {1}'.format(rabbitmq, name)
|
||||
|
||||
if runas is None:
|
||||
runas = salt.utils.get_user()
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False, runas=runas)
|
||||
|
||||
cmd = [_get_rabbitmq_plugin(), 'disable', name]
|
||||
ret = __salt__['cmd.run_all'](cmd, runas=runas, python_shell=False)
|
||||
return _format_response(ret, 'Disabled')
|
||||
|
@ -84,7 +84,7 @@ def _publish(
|
||||
try:
|
||||
peer_data = channel.send(load)
|
||||
except SaltReqTimeoutError:
|
||||
return '{0!r} publish timed out'.format(fun)
|
||||
return '\'{0}\' publish timed out'.format(fun)
|
||||
if not peer_data:
|
||||
return {}
|
||||
# CLI args are passed as strings, re-cast to keep time.sleep happy
|
||||
@ -216,4 +216,4 @@ def runner(fun, arg=None, timeout=5):
|
||||
try:
|
||||
return channel.send(load)
|
||||
except SaltReqTimeoutError:
|
||||
return '{0!r} runner publish timed out'.format(fun)
|
||||
return '\'{0}\' runner publish timed out'.format(fun)
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Manage ruby installations with rbenv. Rbenv is supported on Linux and Mac OS X.
|
||||
Rbenv doesn't work on Windows (and isn't really necessary on Windows as there is
|
||||
Manage ruby installations with rbenv. rbenv is supported on Linux and Mac OS X.
|
||||
rbenv doesn't work on Windows (and isn't really necessary on Windows as there is
|
||||
no system Ruby on Windows). On Windows, the RubyInstaller and/or Pik are both
|
||||
good alternatives to work with multiple versions of Ruby on the same box.
|
||||
|
||||
@ -19,10 +19,10 @@ import shlex
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
from salt.exceptions import SaltInvocationError
|
||||
|
||||
# Import 3rd-party libs
|
||||
import salt.ext.six as six
|
||||
from salt.ext.six.moves import shlex_quote as _cmd_quote # pylint: disable=import-error
|
||||
|
||||
# Set up logger
|
||||
log = logging.getLogger(__name__)
|
||||
@ -38,9 +38,9 @@ __opts__ = {
|
||||
|
||||
|
||||
def __virtual__():
|
||||
"""
|
||||
'''
|
||||
Only work on POSIX-like systems
|
||||
"""
|
||||
'''
|
||||
if salt.utils.is_windows():
|
||||
return False
|
||||
return True
|
||||
@ -66,14 +66,30 @@ def _parse_env(env):
|
||||
env = {}
|
||||
|
||||
for bad_env_key in (x for x, y in six.iteritems(env) if y is None):
|
||||
log.error('Environment variable {0!r} passed without a value. '
|
||||
log.error('Environment variable \'{0}\' passed without a value. '
|
||||
'Setting value to an empty string'.format(bad_env_key))
|
||||
env[bad_env_key] = ''
|
||||
|
||||
return env
|
||||
|
||||
|
||||
def _rbenv_exec(command, args='', env=None, runas=None, ret=None):
|
||||
def _rbenv_bin(runas=None):
|
||||
path = _rbenv_path(runas)
|
||||
return '{0}/bin/rbenv'.format(path)
|
||||
|
||||
|
||||
def _rbenv_path(runas=None):
|
||||
path = None
|
||||
if runas in (None, 'root'):
|
||||
path = __salt__['config.option']('rbenv.root') or '/usr/local/rbenv'
|
||||
else:
|
||||
path = __salt__['config.option']('rbenv.root') \
|
||||
or '~{0}/.rbenv'.format(runas)
|
||||
|
||||
return os.path.expanduser(path)
|
||||
|
||||
|
||||
def _rbenv_exec(command, env=None, runas=None, ret=None):
|
||||
if not is_installed(runas):
|
||||
return False
|
||||
|
||||
@ -83,10 +99,8 @@ def _rbenv_exec(command, args='', env=None, runas=None, ret=None):
|
||||
environ = _parse_env(env)
|
||||
environ['RBENV_ROOT'] = path
|
||||
|
||||
args = ' '.join([_cmd_quote(arg) for arg in _shlex_split(args)])
|
||||
|
||||
result = __salt__['cmd.run_all'](
|
||||
'{0} {1} {2}'.format(binary, _cmd_quote(command), args),
|
||||
[binary] + command,
|
||||
runas=runas,
|
||||
env=environ
|
||||
)
|
||||
@ -101,29 +115,12 @@ def _rbenv_exec(command, args='', env=None, runas=None, ret=None):
|
||||
return False
|
||||
|
||||
|
||||
def _rbenv_bin(runas=None):
|
||||
path = _rbenv_path(runas)
|
||||
return '{0}/bin/rbenv'.format(path)
|
||||
|
||||
|
||||
def _rbenv_path(runas=None):
|
||||
path = None
|
||||
if runas in (None, 'root'):
|
||||
path = __salt__['config.option']('rbenv.root') or '/usr/local/rbenv'
|
||||
else:
|
||||
path = (__salt__['config.option']('rbenv.root') or
|
||||
'~{0}/.rbenv'.format(runas))
|
||||
|
||||
return _cmd_quote(os.path.expanduser(path))
|
||||
|
||||
|
||||
def _install_rbenv(path, runas=None):
|
||||
if os.path.isdir(path):
|
||||
return True
|
||||
|
||||
return 0 == __salt__['cmd.retcode'](
|
||||
'git clone https://github.com/sstephenson/rbenv.git {0}'
|
||||
.format(_cmd_quote(path)), runas=runas)
|
||||
cmd = ['git', 'clone', 'https://github.com/sstephenson/rbenv.git', path]
|
||||
return __salt__['cmd.retcode'](cmd, runas=runas, python_shell=False) == 0
|
||||
|
||||
|
||||
def _install_ruby_build(path, runas=None):
|
||||
@ -131,17 +128,19 @@ def _install_ruby_build(path, runas=None):
|
||||
if os.path.isdir(path):
|
||||
return True
|
||||
|
||||
return 0 == __salt__['cmd.retcode'](
|
||||
'git clone https://github.com/sstephenson/ruby-build.git {0}'
|
||||
.format(_cmd_quote(path)), runas=runas)
|
||||
cmd = ['git', 'clone',
|
||||
'https://github.com/sstephenson/ruby-build.git', path]
|
||||
return __salt__['cmd.retcode'](cmd, runas=runas, python_shell=False) == 0
|
||||
|
||||
|
||||
def _update_rbenv(path, runas=None):
|
||||
if not os.path.isdir(path):
|
||||
return False
|
||||
|
||||
return 0 == __salt__['cmd.retcode'](
|
||||
'git pull', runas=runas, cwd=path)
|
||||
return __salt__['cmd.retcode'](['git', 'pull'],
|
||||
runas=runas,
|
||||
cwd=path,
|
||||
python_shell=False) == 0
|
||||
|
||||
|
||||
def _update_ruby_build(path, runas=None):
|
||||
@ -149,13 +148,15 @@ def _update_ruby_build(path, runas=None):
|
||||
if not os.path.isdir(path):
|
||||
return False
|
||||
|
||||
return 0 == __salt__['cmd.retcode'](
|
||||
'git pull', runas=runas, cwd=path)
|
||||
return __salt__['cmd.retcode'](['git', 'pull'],
|
||||
runas=runas,
|
||||
cwd=path,
|
||||
python_shell=False) == 0
|
||||
|
||||
|
||||
def install(runas=None, path=None):
|
||||
'''
|
||||
Install Rbenv systemwide
|
||||
Install rbenv systemwide
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -170,7 +171,11 @@ def install(runas=None, path=None):
|
||||
|
||||
def update(runas=None, path=None):
|
||||
'''
|
||||
Updates the current versions of Rbenv and Ruby-Build
|
||||
Updates the current versions of rbenv and ruby-build
|
||||
|
||||
runas
|
||||
The user under which to run rbenv. If not specified, then rbenv will be
|
||||
run as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -186,7 +191,7 @@ def update(runas=None, path=None):
|
||||
|
||||
def is_installed(runas=None):
|
||||
'''
|
||||
Check if Rbenv is installed.
|
||||
Check if rbenv is installed
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -203,7 +208,11 @@ def install_ruby(ruby, runas=None):
|
||||
|
||||
ruby
|
||||
The version of Ruby to install, should match one of the
|
||||
versions listed by rbenv.list
|
||||
versions listed by :py:func:`rbenv.list <salt.modules.rbenv.list>`
|
||||
|
||||
runas
|
||||
The user under which to run rbenv. If not specified, then rbenv will be
|
||||
run as the user under which Salt is running.
|
||||
|
||||
Additional environment variables can be configured in pillar /
|
||||
grains / master:
|
||||
@ -236,7 +245,7 @@ def install_ruby(ruby, runas=None):
|
||||
env = ' '.join(env_list)
|
||||
|
||||
ret = {}
|
||||
ret = _rbenv_exec('install', ruby, env=env, runas=runas, ret=ret)
|
||||
ret = _rbenv_exec(['install', ruby], env=env, runas=runas, ret=ret)
|
||||
if ret['retcode'] == 0:
|
||||
rehash(runas=runas)
|
||||
return ret['stderr']
|
||||
@ -252,7 +261,11 @@ def uninstall_ruby(ruby, runas=None):
|
||||
|
||||
ruby
|
||||
The version of ruby to uninstall. Should match one of the versions
|
||||
listed by :mod:`rbenv.versions <salt.modules.rbenv.versions>`
|
||||
listed by :py:func:`rbenv.versions <salt.modules.rbenv.versions>`.
|
||||
|
||||
runas
|
||||
The user under which to run rbenv. If not specified, then rbenv will be
|
||||
run as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -261,15 +274,13 @@ def uninstall_ruby(ruby, runas=None):
|
||||
salt '*' rbenv.uninstall_ruby 2.0.0-p0
|
||||
'''
|
||||
ruby = re.sub(r'^ruby-', '', ruby)
|
||||
|
||||
args = '--force {0}'.format(ruby)
|
||||
_rbenv_exec('uninstall', args, runas=runas)
|
||||
_rbenv_exec(['uninstall', '--force', ruby], runas=runas)
|
||||
return True
|
||||
|
||||
|
||||
def versions(runas=None):
|
||||
'''
|
||||
List the installed versions of ruby.
|
||||
List the installed versions of ruby
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -277,18 +288,18 @@ def versions(runas=None):
|
||||
|
||||
salt '*' rbenv.versions
|
||||
'''
|
||||
ret = _rbenv_exec('versions', '--bare', runas=runas)
|
||||
ret = _rbenv_exec(['versions', '--bare'], runas=runas)
|
||||
return [] if ret is False else ret.splitlines()
|
||||
|
||||
|
||||
def default(ruby=None, runas=None):
|
||||
'''
|
||||
Returns or sets the currently defined default ruby.
|
||||
Returns or sets the currently defined default ruby
|
||||
|
||||
ruby=None
|
||||
ruby
|
||||
The version to set as the default. Should match one of the versions
|
||||
listed by :mod:`rbenv.versions <salt.modules.rbenv.versions>`. Leave
|
||||
blank to return the current default.
|
||||
listed by :py:func:`rbenv.versions <salt.modules.rbenv.versions>`.
|
||||
Leave blank to return the current default.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -298,16 +309,20 @@ def default(ruby=None, runas=None):
|
||||
salt '*' rbenv.default 2.0.0-p0
|
||||
'''
|
||||
if ruby:
|
||||
_rbenv_exec('global', ruby, runas=runas)
|
||||
_rbenv_exec(['global', ruby], runas=runas)
|
||||
return True
|
||||
else:
|
||||
ret = _rbenv_exec('global', runas=runas)
|
||||
ret = _rbenv_exec(['global'], runas=runas)
|
||||
return '' if ret is False else ret.strip()
|
||||
|
||||
|
||||
def list_(runas=None):
|
||||
'''
|
||||
List the installable versions of ruby.
|
||||
List the installable versions of ruby
|
||||
|
||||
runas
|
||||
The user under which to run rbenv. If not specified, then rbenv will be
|
||||
run as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -316,7 +331,7 @@ def list_(runas=None):
|
||||
salt '*' rbenv.list
|
||||
'''
|
||||
ret = []
|
||||
output = _rbenv_exec('install', '--list', runas=runas)
|
||||
output = _rbenv_exec(['install', '--list'], runas=runas)
|
||||
if output:
|
||||
for line in output.splitlines():
|
||||
if line == 'Available versions:':
|
||||
@ -327,7 +342,11 @@ def list_(runas=None):
|
||||
|
||||
def rehash(runas=None):
|
||||
'''
|
||||
Run rbenv rehash to update the installed shims.
|
||||
Run ``rbenv rehash`` to update the installed shims
|
||||
|
||||
runas
|
||||
The user under which to run rbenv. If not specified, then rbenv will be
|
||||
run as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -335,13 +354,13 @@ def rehash(runas=None):
|
||||
|
||||
salt '*' rbenv.rehash
|
||||
'''
|
||||
_rbenv_exec('rehash', runas=runas)
|
||||
_rbenv_exec(['rehash'], runas=runas)
|
||||
return True
|
||||
|
||||
|
||||
def do(cmdline=None, runas=None):
|
||||
def do(cmdline, runas=None):
|
||||
'''
|
||||
Execute a ruby command with rbenv's shims from the user or the system.
|
||||
Execute a ruby command with rbenv's shims from the user or the system
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -350,13 +369,25 @@ def do(cmdline=None, runas=None):
|
||||
salt '*' rbenv.do 'gem list bundler'
|
||||
salt '*' rbenv.do 'gem list bundler' deploy
|
||||
'''
|
||||
if not cmdline:
|
||||
# This is a positional argument so this should never happen, but this
|
||||
# will handle cases where someone explicitly passes a false value for
|
||||
# cmdline.
|
||||
raise SaltInvocationError('Command must be specified')
|
||||
|
||||
path = _rbenv_path(runas)
|
||||
environ = {'PATH': '{0}/shims:{1}'.format(path, os.environ['PATH'])}
|
||||
cmdline = ' '.join([_cmd_quote(cmd) for cmd in _shlex_split(cmdline)])
|
||||
|
||||
try:
|
||||
cmdline = shlex.split(cmdline)
|
||||
except AttributeError:
|
||||
cmdline = shlex.split(str(cmdline))
|
||||
|
||||
result = __salt__['cmd.run_all'](
|
||||
cmdline,
|
||||
runas=runas,
|
||||
env=environ
|
||||
env=environ,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
if result['retcode'] == 0:
|
||||
@ -368,17 +399,28 @@ def do(cmdline=None, runas=None):
|
||||
|
||||
def do_with_ruby(ruby, cmdline, runas=None):
|
||||
'''
|
||||
Execute a ruby command with rbenv's shims using a specific ruby version.
|
||||
Execute a ruby command with rbenv's shims using a specific ruby version
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' rbenv.do_with_ruby 2.0.0-p0 'gem list bundler'
|
||||
salt '*' rbenv.do_with_ruby 2.0.0-p0 'gem list bundler' deploy
|
||||
salt '*' rbenv.do_with_ruby 2.0.0-p0 'gem list bundler' runas=deploy
|
||||
'''
|
||||
if not cmdline:
|
||||
# This is a positional argument so this should never happen, but this
|
||||
# will handle cases where someone explicitly passes a false value for
|
||||
# cmdline.
|
||||
raise SaltInvocationError('Command must be specified')
|
||||
|
||||
try:
|
||||
cmdline = shlex.split(cmdline)
|
||||
except AttributeError:
|
||||
cmdline = shlex.split(str(cmdline))
|
||||
|
||||
if ruby:
|
||||
cmd = 'RBENV_VERSION={0} {1}'.format(ruby, cmdline)
|
||||
cmd = ['RBENV_VERSION={0}'.format(ruby)] + cmdline
|
||||
else:
|
||||
cmd = cmdline
|
||||
|
||||
|
@ -13,10 +13,10 @@ import datetime
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
import salt.utils.decorators as decorators
|
||||
import salt.utils.pkg.rpm
|
||||
# pylint: disable=import-error,redefined-builtin
|
||||
from salt.ext.six.moves import shlex_quote as _cmd_quote
|
||||
from salt.ext.six.moves import zip
|
||||
# pylint: enable=import-error,redefined-builtin
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
@ -93,9 +93,10 @@ def bin_pkg_info(path, saltenv='base'):
|
||||
# with 'none'
|
||||
queryformat = salt.utils.pkg.rpm.QUERYFORMAT.replace('%{REPOID}', 'none')
|
||||
output = __salt__['cmd.run_stdout'](
|
||||
'rpm -qp --queryformat {0} {1}'.format(_cmd_quote(queryformat), path),
|
||||
['rpm', '-qp', '--queryformat', queryformat, path],
|
||||
output_loglevel='trace',
|
||||
ignore_retcode=True
|
||||
ignore_retcode=True,
|
||||
python_shell=False
|
||||
)
|
||||
ret = {}
|
||||
pkginfo = salt.utils.pkg.rpm.parse_pkginfo(
|
||||
@ -120,14 +121,12 @@ def list_pkgs(*packages):
|
||||
salt '*' lowpkg.list_pkgs
|
||||
'''
|
||||
pkgs = {}
|
||||
if not packages:
|
||||
cmd = 'rpm -qa --qf \'%{NAME} %{VERSION}\\n\''
|
||||
else:
|
||||
cmd = 'rpm -q --qf \'%{{NAME}} %{{VERSION}}\\n\' {0}'.format(
|
||||
' '.join(packages)
|
||||
)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
cmd = ['rpm', '-q' if packages else '-qa',
|
||||
'--queryformat', r'%{NAME} %{VERSION}\n']
|
||||
if packages:
|
||||
cmd.extend(packages)
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if 'is not installed' in line:
|
||||
continue
|
||||
comps = line.split()
|
||||
@ -135,7 +134,7 @@ def list_pkgs(*packages):
|
||||
return pkgs
|
||||
|
||||
|
||||
def verify(*package, **kwargs):
|
||||
def verify(*packages, **kwargs):
|
||||
'''
|
||||
Runs an rpm -Va on a system, and returns the results in a dict
|
||||
|
||||
@ -148,8 +147,8 @@ def verify(*package, **kwargs):
|
||||
|
||||
salt '*' lowpkg.verify
|
||||
salt '*' lowpkg.verify httpd
|
||||
salt '*' lowpkg.verify 'httpd postfix'
|
||||
salt '*' lowpkg.verify 'httpd postfix' ignore_types=['config','doc']
|
||||
salt '*' lowpkg.verify httpd postfix
|
||||
salt '*' lowpkg.verify httpd postfix ignore_types=['config','doc']
|
||||
'''
|
||||
ftypes = {'c': 'config',
|
||||
'd': 'doc',
|
||||
@ -158,17 +157,17 @@ def verify(*package, **kwargs):
|
||||
'r': 'readme'}
|
||||
ret = {}
|
||||
ignore_types = kwargs.get('ignore_types', [])
|
||||
if package:
|
||||
packages = ' '.join(package)
|
||||
cmd = 'rpm -V {0}'.format(packages)
|
||||
if packages:
|
||||
cmd = ['rpm', '-V']
|
||||
# Can't concatenate a tuple, must do a list.extend()
|
||||
cmd.extend(packages)
|
||||
else:
|
||||
cmd = 'rpm -Va'
|
||||
out = __salt__['cmd.run'](
|
||||
cmd,
|
||||
python_shell=False,
|
||||
cmd = ['rpm', '-Va']
|
||||
out = __salt__['cmd.run'](cmd,
|
||||
output_loglevel='trace',
|
||||
ignore_retcode=True)
|
||||
for line in out.splitlines():
|
||||
ignore_retcode=True,
|
||||
python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
fdict = {'mismatch': []}
|
||||
if 'missing' in line:
|
||||
line = ' ' + line
|
||||
@ -217,8 +216,8 @@ def modified(*packages, **flags):
|
||||
'''
|
||||
ret = __salt__['cmd.run_all'](
|
||||
['rpm', '-Va'] + list(packages),
|
||||
python_shell=False,
|
||||
output_loglevel='trace')
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
|
||||
data = {}
|
||||
|
||||
@ -233,7 +232,7 @@ def modified(*packages, **flags):
|
||||
|
||||
ptrn = re.compile(r"\s+")
|
||||
changes = cfg = f_name = None
|
||||
for f_info in ret['stdout'].splitlines():
|
||||
for f_info in salt.utils.itertools.split(ret['stdout'], '\n'):
|
||||
f_info = ptrn.split(f_info)
|
||||
if len(f_info) == 3: # Config file
|
||||
changes, cfg, f_name = f_info
|
||||
@ -244,7 +243,7 @@ def modified(*packages, **flags):
|
||||
'owner', 'group', 'time', 'capabilities']
|
||||
changes = list(changes)
|
||||
if len(changes) == 8: # Older RPMs do not support capabilities
|
||||
changes.append(".")
|
||||
changes.append('.')
|
||||
stats = []
|
||||
for k, v in zip(keys, changes):
|
||||
if v != '.':
|
||||
@ -288,13 +287,15 @@ def file_list(*packages):
|
||||
salt '*' lowpkg.file_list
|
||||
'''
|
||||
if not packages:
|
||||
cmd = 'rpm -qla'
|
||||
cmd = ['rpm', '-qla']
|
||||
else:
|
||||
cmd = 'rpm -ql {0}'.format(' '.join(packages))
|
||||
cmd = ['rpm', '-ql']
|
||||
# Can't concatenate a tuple, must do a list.extend()
|
||||
cmd.extend(packages)
|
||||
ret = __salt__['cmd.run'](
|
||||
cmd,
|
||||
python_shell=False,
|
||||
output_loglevel='trace').splitlines()
|
||||
output_loglevel='trace',
|
||||
python_shell=False).splitlines()
|
||||
return {'errors': [], 'files': ret}
|
||||
|
||||
|
||||
@ -315,14 +316,12 @@ def file_dict(*packages):
|
||||
errors = []
|
||||
ret = {}
|
||||
pkgs = {}
|
||||
if not packages:
|
||||
cmd = 'rpm -qa --qf \'%{NAME} %{VERSION}\\n\''
|
||||
else:
|
||||
cmd = 'rpm -q --qf \'%{{NAME}} %{{VERSION}}\\n\' {0}'.format(
|
||||
' '.join(packages)
|
||||
)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
cmd = ['rpm', '-q' if packages else '-qa',
|
||||
'--queryformat', r'%{NAME} %{VERSION}\n']
|
||||
if packages:
|
||||
cmd.extend(packages)
|
||||
out = __salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
if 'is not installed' in line:
|
||||
errors.append(line)
|
||||
continue
|
||||
@ -330,11 +329,12 @@ def file_dict(*packages):
|
||||
pkgs[comps[0]] = {'version': comps[1]}
|
||||
for pkg in pkgs:
|
||||
files = []
|
||||
cmd = 'rpm -ql {0}'.format(pkg)
|
||||
out = __salt__['cmd.run'](cmd, python_shell=False, output_loglevel='trace')
|
||||
for line in out.splitlines():
|
||||
files.append(line)
|
||||
ret[pkg] = files
|
||||
cmd = ['rpm', '-ql', pkg]
|
||||
out = __salt__['cmd.run'](
|
||||
['rpm', '-ql', pkg],
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
ret[pkg] = out.splitlines()
|
||||
return {'errors': errors, 'packages': ret}
|
||||
|
||||
|
||||
@ -358,10 +358,11 @@ def owner(*paths):
|
||||
if not paths:
|
||||
return ''
|
||||
ret = {}
|
||||
cmd = 'rpm -qf --queryformat "%{{NAME}}" {0!r}'
|
||||
for path in paths:
|
||||
ret[path] = __salt__['cmd.run_stdout'](cmd.format(path),
|
||||
output_loglevel='trace')
|
||||
cmd = ['rpm', '-qf', '--queryformat', '%{{NAME}}', path]
|
||||
ret[path] = __salt__['cmd.run_stdout'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
if 'not owned' in ret[path].lower():
|
||||
ret[path] = ''
|
||||
if len(ret) == 1:
|
||||
@ -392,9 +393,11 @@ def diff(package, path):
|
||||
cmd = "rpm2cpio {0} " \
|
||||
"| cpio -i --quiet --to-stdout .{1} " \
|
||||
"| diff -u --label 'A {1}' --from-file=- --label 'B {1}' {1}"
|
||||
res = __salt__['cmd.shell'](cmd.format(package, path), output_loglevel='trace')
|
||||
res = __salt__['cmd.shell'](cmd.format(package, path),
|
||||
output_loglevel='trace')
|
||||
if res and res.startswith('Binary file'):
|
||||
return 'File "{0}" is binary and its content has been modified.'.format(path)
|
||||
return 'File \'{0}\' is binary and its content has been ' \
|
||||
'modified.'.format(path)
|
||||
|
||||
return res
|
||||
|
||||
|
@ -10,11 +10,12 @@ Options passed into opts will overwrite options passed into pillar.
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import python libs
|
||||
import errno
|
||||
import logging
|
||||
import os
|
||||
|
||||
# Import salt libs
|
||||
from salt.exceptions import CommandExecutionError
|
||||
import salt.utils
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -32,15 +33,14 @@ def _check(delete, force, update, passwordfile, exclude, excludefrom):
|
||||
if update:
|
||||
options.append('--update')
|
||||
if passwordfile:
|
||||
options.append('--password-file={0}'.format(passwordfile))
|
||||
options.extend(['--password-file', passwordfile])
|
||||
if excludefrom:
|
||||
options.append('--exclude-from={0}'.format(excludefrom))
|
||||
options.extend(['--exclude-from', excludefrom])
|
||||
if exclude:
|
||||
exclude = None
|
||||
exclude = False
|
||||
if exclude:
|
||||
options.append('--exclude={0}'.format(exclude))
|
||||
|
||||
return ' '.join(options)
|
||||
options.extend(['--exclude', exclude])
|
||||
return options
|
||||
|
||||
|
||||
def rsync(src,
|
||||
@ -50,9 +50,13 @@ def rsync(src,
|
||||
update=False,
|
||||
passwordfile=None,
|
||||
exclude=None,
|
||||
excludefrom=None,
|
||||
):
|
||||
excludefrom=None):
|
||||
'''
|
||||
.. versionchanged:: Boron
|
||||
Return data now contains just the output of the rsync command, instead
|
||||
of a dictionary as returned from :py:func:`cmd.run_all
|
||||
<salt.modules.cmdmod.run_all>`.
|
||||
|
||||
Rsync files from src to dst
|
||||
|
||||
CLI Example:
|
||||
@ -79,29 +83,24 @@ def rsync(src,
|
||||
if not excludefrom:
|
||||
excludefrom = __salt__['config.option']('rsync.excludefrom')
|
||||
if not src or not dst:
|
||||
raise CommandExecutionError('ERROR: src and dst cannot be empty.')
|
||||
raise SaltInvocationError('src and dst cannot be empty')
|
||||
|
||||
option = _check(delete, force, update, passwordfile, exclude, excludefrom)
|
||||
cmd = (
|
||||
r'''rsync {option} {src} {dst}'''
|
||||
.format(
|
||||
option=option,
|
||||
src=src,
|
||||
dst=dst,
|
||||
)
|
||||
)
|
||||
|
||||
cmd = ['rsync'] + option + [src, dst]
|
||||
try:
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
return __salt__['cmd.run'](cmd, python_shell=False)
|
||||
except (IOError, OSError) as exc:
|
||||
raise CommandExecutionError(exc.strerror)
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def version():
|
||||
'''
|
||||
Return rsync version
|
||||
.. versionchanged:: Boron
|
||||
Return data now contains just the version number as a string, instead
|
||||
of a dictionary as returned from :py:func:`cmd.run_all
|
||||
<salt.modules.cmdmod.run_all>`.
|
||||
|
||||
Returns rsync version
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -109,21 +108,29 @@ def version():
|
||||
|
||||
salt '*' rsync.version
|
||||
'''
|
||||
|
||||
cmd = (r'''rsync --version''')
|
||||
|
||||
try:
|
||||
ret = __salt__['cmd.run_all'](cmd)
|
||||
out = __salt__['cmd.run_stdout'](
|
||||
['rsync', '--version'],
|
||||
python_shell=False)
|
||||
except (IOError, OSError) as exc:
|
||||
raise CommandExecutionError(exc.strerror)
|
||||
|
||||
ret['stdout'] = ret['stdout'].split('\n')[0].split()[2]
|
||||
return ret
|
||||
try:
|
||||
return out.split('\n')[0].split()[2]
|
||||
except IndexError:
|
||||
raise CommandExecutionError('Unable to determine rsync version')
|
||||
|
||||
|
||||
def config(confile='/etc/rsyncd.conf'):
|
||||
def config(conf_path='/etc/rsyncd.conf'):
|
||||
'''
|
||||
Return rsync config
|
||||
.. versionchanged:: Boron
|
||||
Return data now contains just the contents of the rsyncd.conf as a
|
||||
string, instead of a dictionary as returned from :py:func:`cmd.run_all
|
||||
<salt.modules.cmdmod.run_all>`.
|
||||
|
||||
Returns the contents of the rsync config file
|
||||
|
||||
conf_path : /etc/rsyncd.conf
|
||||
Path to the config file
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -131,20 +138,25 @@ def config(confile='/etc/rsyncd.conf'):
|
||||
|
||||
salt '*' rsync.config
|
||||
'''
|
||||
|
||||
if not os.path.isfile(confile):
|
||||
raise CommandExecutionError('{0!r} does not exit'.format(confile))
|
||||
|
||||
cmd = (
|
||||
r'''cat {confile}'''
|
||||
.format(
|
||||
confile=confile
|
||||
)
|
||||
)
|
||||
|
||||
ret = ''
|
||||
try:
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
except (IOError, OSError) as exc:
|
||||
raise CommandExecutionError(exc.strerror)
|
||||
|
||||
with salt.utils.fopen(conf_path, 'r') as fp_:
|
||||
for line in fp_:
|
||||
ret += line
|
||||
except IOError as exc:
|
||||
if exc.errno == errno.ENOENT:
|
||||
raise CommandExecutionError('{0} does not exist'.format(conf_path))
|
||||
elif exc.errno == errno.EACCES:
|
||||
raise CommandExecutionError(
|
||||
'Unable to read {0}, access denied'.format(conf_path)
|
||||
)
|
||||
elif exc.errno == errno.EISDIR:
|
||||
raise CommandExecutionError(
|
||||
'Unable to read {0}, path is a directory'.format(conf_path)
|
||||
)
|
||||
else:
|
||||
raise CommandExecutionError(
|
||||
'Error {0}: {1}'.format(exc.errno, exc.strerror)
|
||||
)
|
||||
else:
|
||||
return ret
|
||||
|
@ -8,10 +8,10 @@ from __future__ import absolute_import
|
||||
import re
|
||||
import os
|
||||
import logging
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
import shlex
|
||||
|
||||
# Import salt libs
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -30,21 +30,22 @@ def _get_rvm_location(runas=None):
|
||||
runas_home = os.path.expanduser('~{0}'.format(runas))
|
||||
rvmpath = '{0}/.rvm/bin/rvm'.format(runas_home)
|
||||
if os.path.exists(rvmpath):
|
||||
return rvmpath
|
||||
return '/usr/local/rvm/bin/rvm'
|
||||
return [rvmpath]
|
||||
return ['/usr/local/rvm/bin/rvm']
|
||||
|
||||
|
||||
def _rvm(command, arguments=None, runas=None, cwd=None):
|
||||
def _rvm(command, runas=None, cwd=None):
|
||||
if runas is None:
|
||||
runas = __salt__['config.option']('rvm.runas')
|
||||
if not is_installed(runas):
|
||||
return False
|
||||
|
||||
cmd = [_get_rvm_location(runas), _cmd_quote(command)]
|
||||
if arguments:
|
||||
cmd.extend([_cmd_quote(arg) for arg in arguments.split()])
|
||||
cmd = _get_rvm_location(runas) + command
|
||||
|
||||
ret = __salt__['cmd.run_all'](' '.join(cmd), runas=runas, cwd=cwd)
|
||||
ret = __salt__['cmd.run_all'](cmd,
|
||||
runas=runas,
|
||||
cwd=cwd,
|
||||
python_shell=False)
|
||||
|
||||
if ret['retcode'] == 0:
|
||||
return ret['stdout']
|
||||
@ -52,9 +53,7 @@ def _rvm(command, arguments=None, runas=None, cwd=None):
|
||||
|
||||
|
||||
def _rvm_do(ruby, command, runas=None, cwd=None):
|
||||
return _rvm('{ruby}'.format(ruby=ruby or 'default'),
|
||||
arguments='do {command}'.format(command=command),
|
||||
runas=runas, cwd=cwd)
|
||||
return _rvm([ruby or 'default', 'do'] + command, runas=runas, cwd=cwd)
|
||||
|
||||
|
||||
def is_installed(runas=None):
|
||||
@ -67,12 +66,19 @@ def is_installed(runas=None):
|
||||
|
||||
salt '*' rvm.is_installed
|
||||
'''
|
||||
return __salt__['cmd.has_exec'](_get_rvm_location(runas))
|
||||
try:
|
||||
return __salt__['cmd.has_exec'](_get_rvm_location(runas)[0])
|
||||
except IndexError:
|
||||
return False
|
||||
|
||||
|
||||
def install(runas=None):
|
||||
'''
|
||||
Install RVM system wide.
|
||||
Install RVM system-wide
|
||||
|
||||
runas
|
||||
The user under which to run the rvm installer script. If not specified,
|
||||
then it be run as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -91,11 +97,10 @@ def install(runas=None):
|
||||
python_shell=True
|
||||
)
|
||||
if ret['retcode'] > 0:
|
||||
log.debug(
|
||||
'Error while downloading the RVM installer. Command '
|
||||
'returned: {0!r}'.format(ret)
|
||||
)
|
||||
return False
|
||||
msg = 'Error encountered while downloading the RVM installer'
|
||||
if ret['stderr']:
|
||||
msg += '. stderr follows:\n\n' + ret['stderr']
|
||||
raise CommandExecutionError(msg)
|
||||
return True
|
||||
|
||||
|
||||
@ -104,9 +109,11 @@ def install_ruby(ruby, runas=None):
|
||||
Install a ruby implementation.
|
||||
|
||||
ruby
|
||||
The version of ruby to install.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The version of ruby to install
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -120,20 +127,22 @@ def install_ruby(ruby, runas=None):
|
||||
# libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev autoconf libc6-dev
|
||||
# libncurses5-dev automake libtool bison subversion ruby
|
||||
if runas and runas != 'root':
|
||||
_rvm('autolibs', 'disable {ruby}'.format(ruby=ruby), runas=runas)
|
||||
return _rvm('install', '--disable-binary {ruby}'.format(ruby=ruby), runas=runas)
|
||||
_rvm(['autolibs', 'disable', ruby], runas=runas)
|
||||
return _rvm(['install', '--disable-binary', ruby], runas=runas)
|
||||
else:
|
||||
return _rvm('install', ruby, runas=runas)
|
||||
return _rvm(['install', ruby], runas=runas)
|
||||
|
||||
|
||||
def reinstall_ruby(ruby, runas=None):
|
||||
'''
|
||||
Reinstall a ruby implementation.
|
||||
Reinstall a ruby implementation
|
||||
|
||||
ruby
|
||||
The version of ruby to reinstall.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The version of ruby to reinstall
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -141,15 +150,16 @@ def reinstall_ruby(ruby, runas=None):
|
||||
|
||||
salt '*' rvm.reinstall_ruby 1.9.3-p385
|
||||
'''
|
||||
return _rvm('reinstall', ruby, runas=runas)
|
||||
return _rvm(['reinstall', ruby], runas=runas)
|
||||
|
||||
|
||||
def list_(runas=None):
|
||||
'''
|
||||
List all rvm installed rubies.
|
||||
List all rvm-installed rubies
|
||||
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -158,7 +168,7 @@ def list_(runas=None):
|
||||
salt '*' rvm.list
|
||||
'''
|
||||
rubies = []
|
||||
output = _rvm('list', '', runas=runas)
|
||||
output = _rvm(['list'], runas=runas)
|
||||
if output:
|
||||
regex = re.compile(r'^[= ]([*> ]) ([^- ]+)-([^ ]+) \[ (.*) \]')
|
||||
for line in output.splitlines():
|
||||
@ -172,12 +182,14 @@ def list_(runas=None):
|
||||
|
||||
def set_default(ruby, runas=None):
|
||||
'''
|
||||
Set the default ruby.
|
||||
Set the default ruby
|
||||
|
||||
ruby
|
||||
The version of ruby to make the default.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The version of ruby to make the default
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -185,18 +197,15 @@ def set_default(ruby, runas=None):
|
||||
|
||||
salt '*' rvm.set_default 2.0.0
|
||||
'''
|
||||
return _rvm('alias',
|
||||
'create default {ruby}'.format(ruby=ruby), runas=runas)
|
||||
return _rvm(['alias', 'create', 'default', ruby], runas=runas)
|
||||
|
||||
|
||||
def get(version='stable', runas=None):
|
||||
'''
|
||||
Update RVM.
|
||||
Update RVM
|
||||
|
||||
version : stable
|
||||
Which version of RVM to install, e.g. stable or head.
|
||||
ruby
|
||||
The version of ruby to reinstall.
|
||||
Which version of RVM to install, (e.g. stable or head)
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -204,19 +213,23 @@ def get(version='stable', runas=None):
|
||||
|
||||
salt '*' rvm.get
|
||||
'''
|
||||
return _rvm('get', version, runas=runas)
|
||||
return _rvm(['get', version], runas=runas)
|
||||
|
||||
|
||||
def wrapper(ruby_string, wrapper_prefix, runas=None, *binaries):
|
||||
'''
|
||||
Install RVM wrapper scripts.
|
||||
Install RVM wrapper scripts
|
||||
|
||||
ruby_string
|
||||
Ruby/gemset to install wrappers for.
|
||||
Ruby/gemset to install wrappers for
|
||||
|
||||
wrapper_prefix
|
||||
What to prepend to the name of the generated wrapper binaries.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
What to prepend to the name of the generated wrapper binaries
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
binaries : None
|
||||
The names of the binaries to create wrappers for. When nothing is
|
||||
given, wrappers for ruby, gem, rake, irb, rdoc, ri and testrb are
|
||||
@ -228,26 +241,25 @@ def wrapper(ruby_string, wrapper_prefix, runas=None, *binaries):
|
||||
|
||||
salt '*' rvm.wrapper <ruby_string> <wrapper_prefix>
|
||||
'''
|
||||
return _rvm('wrapper',
|
||||
'{ruby_string} {wrapper_prefix} {binaries}'.format(
|
||||
ruby_string=ruby_string,
|
||||
wrapper_prefix=wrapper_prefix,
|
||||
binaries=' '.join(binaries)
|
||||
),
|
||||
runas=runas)
|
||||
cmd = ['wrapper', ruby_string, wrapper_prefix]
|
||||
cmd.extend(binaries)
|
||||
return _rvm(cmd, runas=runas)
|
||||
|
||||
|
||||
def rubygems(ruby, version, runas=None):
|
||||
'''
|
||||
Installs a specific rubygems version in the given ruby.
|
||||
Installs a specific rubygems version in the given ruby
|
||||
|
||||
ruby
|
||||
The ruby to install rubygems for.
|
||||
The ruby for which to install rubygems
|
||||
|
||||
version
|
||||
The version of rubygems to install or 'remove' to use the version that
|
||||
The version of rubygems to install, or 'remove' to use the version that
|
||||
ships with 1.9
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -255,7 +267,7 @@ def rubygems(ruby, version, runas=None):
|
||||
|
||||
salt '*' rvm.rubygems 2.0.0 1.8.24
|
||||
'''
|
||||
return _rvm_do(ruby, 'rubygems {0}'.format(version), runas=runas)
|
||||
return _rvm_do(ruby, ['rubygems', version], runas=runas)
|
||||
|
||||
|
||||
def gemset_create(ruby, gemset, runas=None):
|
||||
@ -263,11 +275,14 @@ def gemset_create(ruby, gemset, runas=None):
|
||||
Creates a gemset.
|
||||
|
||||
ruby
|
||||
The ruby version to create the gemset for.
|
||||
The ruby version for which to create the gemset
|
||||
|
||||
gemset
|
||||
The name of the gemset to create.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The name of the gemset to create
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -275,9 +290,7 @@ def gemset_create(ruby, gemset, runas=None):
|
||||
|
||||
salt '*' rvm.gemset_create 2.0.0 foobar
|
||||
'''
|
||||
return _rvm_do(ruby,
|
||||
'rvm gemset create {gemset}'.format(gemset=gemset),
|
||||
runas=runas)
|
||||
return _rvm_do(ruby, ['rvm', 'gemset', 'create', gemset], runas=runas)
|
||||
|
||||
|
||||
def gemset_list(ruby='default', runas=None):
|
||||
@ -285,9 +298,11 @@ def gemset_list(ruby='default', runas=None):
|
||||
List all gemsets for the given ruby.
|
||||
|
||||
ruby : default
|
||||
The ruby version to list the gemsets for
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The ruby version for which to list the gemsets
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -296,7 +311,7 @@ def gemset_list(ruby='default', runas=None):
|
||||
salt '*' rvm.gemset_list
|
||||
'''
|
||||
gemsets = []
|
||||
output = _rvm_do(ruby, 'rvm gemset list', runas=runas)
|
||||
output = _rvm_do(ruby, ['rvm', 'gemset', 'list'], runas=runas)
|
||||
if output:
|
||||
regex = re.compile('^ ([^ ]+)')
|
||||
for line in output.splitlines():
|
||||
@ -308,14 +323,17 @@ def gemset_list(ruby='default', runas=None):
|
||||
|
||||
def gemset_delete(ruby, gemset, runas=None):
|
||||
'''
|
||||
Deletes a gemset.
|
||||
Delete a gemset
|
||||
|
||||
ruby
|
||||
The ruby version the gemset belongs to.
|
||||
The ruby version to which the gemset belongs
|
||||
|
||||
gemset
|
||||
The gemset to delete.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The gemset to delete
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -324,7 +342,7 @@ def gemset_delete(ruby, gemset, runas=None):
|
||||
salt '*' rvm.gemset_delete 2.0.0 foobar
|
||||
'''
|
||||
return _rvm_do(ruby,
|
||||
'rvm --force gemset delete {gemset}'.format(gemset=gemset),
|
||||
['rvm', '--force', 'gemset', 'delete', gemset],
|
||||
runas=runas)
|
||||
|
||||
|
||||
@ -333,11 +351,14 @@ def gemset_empty(ruby, gemset, runas=None):
|
||||
Remove all gems from a gemset.
|
||||
|
||||
ruby
|
||||
The ruby version the gemset belongs to.
|
||||
The ruby version to which the gemset belongs
|
||||
|
||||
gemset
|
||||
The gemset to empty.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The gemset to empty
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -346,7 +367,7 @@ def gemset_empty(ruby, gemset, runas=None):
|
||||
salt '*' rvm.gemset_empty 2.0.0 foobar
|
||||
'''
|
||||
return _rvm_do(ruby,
|
||||
'rvm --force gemset empty {gemset}'.format(gemset=gemset),
|
||||
['rvm', '--force', 'gemset', 'empty', gemset],
|
||||
runas=runas)
|
||||
|
||||
|
||||
@ -355,11 +376,14 @@ def gemset_copy(source, destination, runas=None):
|
||||
Copy all gems from one gemset to another.
|
||||
|
||||
source
|
||||
The name of the gemset to copy, complete with ruby version.
|
||||
The name of the gemset to copy, complete with ruby version
|
||||
|
||||
destination
|
||||
The destination gemset.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
The destination gemset
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -367,7 +391,7 @@ def gemset_copy(source, destination, runas=None):
|
||||
|
||||
salt '*' rvm.gemset_copy foobar bazquo
|
||||
'''
|
||||
return _rvm('gemset copy {0} {1}'.format(source, destination), runas=runas)
|
||||
return _rvm(['gemset', 'copy', source, destination], runas=runas)
|
||||
|
||||
|
||||
def gemset_list_all(runas=None):
|
||||
@ -376,8 +400,9 @@ def gemset_list_all(runas=None):
|
||||
|
||||
Note that you must have set a default ruby before this can work.
|
||||
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -387,7 +412,7 @@ def gemset_list_all(runas=None):
|
||||
'''
|
||||
gemsets = {}
|
||||
current_ruby = None
|
||||
output = _rvm_do('default', 'rvm gemset list_all', runas=runas)
|
||||
output = _rvm_do('default', ['rvm', 'gemset', 'list_all'], runas=runas)
|
||||
if output:
|
||||
gems_regex = re.compile('^ ([^ ]+)')
|
||||
gemset_regex = re.compile('^gemsets for ([^ ]+)')
|
||||
@ -406,14 +431,19 @@ def do(ruby, command, runas=None, cwd=None): # pylint: disable=C0103
|
||||
'''
|
||||
Execute a command in an RVM controlled environment.
|
||||
|
||||
ruby:
|
||||
The ruby to use.
|
||||
command:
|
||||
The command to execute.
|
||||
runas : None
|
||||
The user to run rvm as.
|
||||
cwd : None
|
||||
The current working directory.
|
||||
ruby
|
||||
Which ruby to use
|
||||
|
||||
command
|
||||
The rvm command to execute
|
||||
|
||||
runas
|
||||
The user under which to run rvm. If not specified, then rvm will be run
|
||||
as the user under which Salt is running.
|
||||
|
||||
cwd
|
||||
The directory from which to run the rvm command. Defaults to the user's
|
||||
home directory.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -421,4 +451,8 @@ def do(ruby, command, runas=None, cwd=None): # pylint: disable=C0103
|
||||
|
||||
salt '*' rvm.do 2.0.0 <command>
|
||||
'''
|
||||
try:
|
||||
command = shlex.split(command)
|
||||
except AttributeError:
|
||||
command = shlex.split(str(command))
|
||||
return _rvm_do(ruby, command, runas=runas, cwd=cwd)
|
||||
|
@ -95,14 +95,14 @@ def _sync(form, saltenv=None):
|
||||
source = salt.utils.url.create('_' + form)
|
||||
mod_dir = os.path.join(__opts__['extension_modules'], '{0}'.format(form))
|
||||
if not os.path.isdir(mod_dir):
|
||||
log.info('Creating module dir {0!r}'.format(mod_dir))
|
||||
log.info('Creating module dir \'{0}\''.format(mod_dir))
|
||||
try:
|
||||
os.makedirs(mod_dir)
|
||||
except (IOError, OSError):
|
||||
msg = 'Cannot create cache module directory {0}. Check permissions.'
|
||||
log.error(msg.format(mod_dir))
|
||||
for sub_env in saltenv:
|
||||
log.info('Syncing {0} for environment {1!r}'.format(form, sub_env))
|
||||
log.info('Syncing {0} for environment \'{1}\''.format(form, sub_env))
|
||||
cache = []
|
||||
log.info('Loading cache from {0}, for {1})'.format(source, sub_env))
|
||||
# Grab only the desired files (.py, .pyx, .so)
|
||||
@ -117,13 +117,13 @@ def _sync(form, saltenv=None):
|
||||
sub_env,
|
||||
'_{0}'.format(form)
|
||||
)
|
||||
log.debug('Local cache dir: {0!r}'.format(local_cache_dir))
|
||||
log.debug('Local cache dir: \'{0}\''.format(local_cache_dir))
|
||||
for fn_ in cache:
|
||||
relpath = os.path.relpath(fn_, local_cache_dir)
|
||||
relname = os.path.splitext(relpath)[0].replace(os.sep, '.')
|
||||
remote.add(relpath)
|
||||
dest = os.path.join(mod_dir, relpath)
|
||||
log.info('Copying {0!r} to {1!r}'.format(fn_, dest))
|
||||
log.info('Copying \'{0}\' to \'{1}\''.format(fn_, dest))
|
||||
if os.path.isfile(dest):
|
||||
# The file is present, if the sum differs replace it
|
||||
hash_type = __opts__.get('hash_type', 'md5')
|
||||
|
@ -268,7 +268,7 @@ def _check_install(root):
|
||||
sh_ = '/bin/bash'
|
||||
|
||||
cmd = ('if ! type salt-minion; then exit 1; fi')
|
||||
cmd = 'chroot \'{0}\' {1} -c {2!r}'.format(
|
||||
cmd = 'chroot \'{0}\' {1} -c \'{2}\''.format(
|
||||
root,
|
||||
sh_,
|
||||
cmd)
|
||||
|
@ -7,14 +7,15 @@ Manage users with the useradd command
|
||||
from __future__ import absolute_import
|
||||
try:
|
||||
import pwd
|
||||
HAS_PWD = True
|
||||
except ImportError:
|
||||
pass
|
||||
HAS_PWD = False
|
||||
import copy
|
||||
import logging
|
||||
from copy import deepcopy
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
from salt.ext.six import string_types
|
||||
import salt.ext.six as six
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -27,8 +28,14 @@ def __virtual__():
|
||||
'''
|
||||
Set the user module if the kernel is SunOS
|
||||
'''
|
||||
|
||||
return __virtualname__ if __grains__['kernel'] == 'SunOS' else False
|
||||
if __grains__['kernel'] == 'SunOS':
|
||||
if not HAS_PWD:
|
||||
log.warning(
|
||||
'pwd module not found, user management will not be possible'
|
||||
)
|
||||
else:
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
|
||||
def _get_gecos(name):
|
||||
@ -59,6 +66,25 @@ def _build_gecos(gecos_dict):
|
||||
gecos_dict.get('homephone', ''))
|
||||
|
||||
|
||||
def _update_gecos(name, key, value):
|
||||
'''
|
||||
Common code to change a user's GECOS information
|
||||
'''
|
||||
if not isinstance(value, six.string_types):
|
||||
value = str(value)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if value == pre_info[key]:
|
||||
return True
|
||||
gecos_data = copy.deepcopy(pre_info)
|
||||
gecos_data[key] = value
|
||||
cmd = ['usermod', '-c', _build_gecos(gecos_data), name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
return _get_gecos(name).get(key) == value
|
||||
|
||||
|
||||
def add(name,
|
||||
uid=None,
|
||||
gid=None,
|
||||
@ -87,32 +113,26 @@ def add(name,
|
||||
if kwargs:
|
||||
log.warning('Invalid kwargs passed to user.add')
|
||||
|
||||
if isinstance(groups, string_types):
|
||||
if isinstance(groups, six.string_types):
|
||||
groups = groups.split(',')
|
||||
cmd = 'useradd '
|
||||
cmd = ['useradd']
|
||||
if shell:
|
||||
cmd += '-s {0} '.format(shell)
|
||||
cmd.extend(['-s', shell])
|
||||
if uid:
|
||||
cmd += '-u {0} '.format(uid)
|
||||
cmd.extend(['-u', uid])
|
||||
if gid:
|
||||
cmd += '-g {0} '.format(gid)
|
||||
cmd.extend(['-g', gid])
|
||||
if groups:
|
||||
cmd += '-G {0} '.format(','.join(groups))
|
||||
|
||||
if home is None:
|
||||
cmd.extend(['-G', ','.join(groups)])
|
||||
if createhome:
|
||||
cmd += '-m '
|
||||
else:
|
||||
if createhome:
|
||||
cmd += '-m -d {0} '.format(home)
|
||||
else:
|
||||
cmd += '-d {0} '.format(home)
|
||||
|
||||
cmd.append('-m')
|
||||
if home is not None:
|
||||
cmd.extend(['-d', home])
|
||||
if not unique:
|
||||
cmd += '-o '
|
||||
cmd += name
|
||||
ret = __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
if ret != 0:
|
||||
cmd.append('-o')
|
||||
cmd.append(name)
|
||||
|
||||
if __salt__['cmd.retcode'](cmd, python_shell=False) != 0:
|
||||
return False
|
||||
else:
|
||||
# At this point, the user was successfully created, so return true
|
||||
@ -145,16 +165,15 @@ def delete(name, remove=False, force=False):
|
||||
salt '*' user.delete name remove=True force=True
|
||||
'''
|
||||
if salt.utils.is_true(force):
|
||||
log.error('userdel does not support force-deleting user while '
|
||||
'user is logged in')
|
||||
cmd = 'userdel '
|
||||
log.warning(
|
||||
'userdel does not support force-deleting user while user is '
|
||||
'logged in'
|
||||
)
|
||||
cmd = ['userdel']
|
||||
if remove:
|
||||
cmd += '-r '
|
||||
cmd += name
|
||||
|
||||
ret = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
return not ret['retcode']
|
||||
cmd.append('-r')
|
||||
cmd.append(name)
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def getent(refresh=False):
|
||||
@ -188,14 +207,15 @@ def chuid(name, uid):
|
||||
salt '*' user.chuid foo 4376
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if uid == pre_info['uid']:
|
||||
return True
|
||||
cmd = 'usermod -u {0} {1}'.format(uid, name)
|
||||
cmd = ['usermod', '-u', uid, name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['uid'] != pre_info['uid']:
|
||||
return post_info['uid'] == uid
|
||||
return False
|
||||
return info(name).get('uid') == uid
|
||||
|
||||
|
||||
def chgid(name, gid):
|
||||
@ -209,14 +229,15 @@ def chgid(name, gid):
|
||||
salt '*' user.chgid foo 4376
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if gid == pre_info['gid']:
|
||||
return True
|
||||
cmd = 'usermod -g {0} {1}'.format(gid, name)
|
||||
cmd = ['usermod', '-g', gid, name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['gid'] != pre_info['gid']:
|
||||
return post_info['gid'] == gid
|
||||
return False
|
||||
return info(name).get('gid') == gid
|
||||
|
||||
|
||||
def chshell(name, shell):
|
||||
@ -230,20 +251,31 @@ def chshell(name, shell):
|
||||
salt '*' user.chshell foo /bin/zsh
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if shell == pre_info['shell']:
|
||||
return True
|
||||
cmd = 'usermod -s {0} {1}'.format(shell, name)
|
||||
cmd = ['usermod', '-s', shell, name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['shell'] != pre_info['shell']:
|
||||
return post_info['shell'] == shell
|
||||
return False
|
||||
return info(name).get('shell') == shell
|
||||
|
||||
|
||||
def chhome(name, home, persist=False):
|
||||
'''
|
||||
Change the home directory of the user, pass true for persist to copy files
|
||||
to the new home dir
|
||||
Set a new home directory for an existing user
|
||||
|
||||
name
|
||||
Username to modify
|
||||
|
||||
home
|
||||
New home directory to set
|
||||
|
||||
persist : False
|
||||
Set to ``True`` to prevent configuration files in the new home
|
||||
directory from being overwritten by the files from the skeleton
|
||||
directory.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -252,23 +284,35 @@ def chhome(name, home, persist=False):
|
||||
salt '*' user.chhome foo /home/users/foo True
|
||||
'''
|
||||
pre_info = info(name)
|
||||
if not pre_info:
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' does not exist'.format(name)
|
||||
)
|
||||
if home == pre_info['home']:
|
||||
return True
|
||||
cmd = 'usermod -d {0} '.format(home)
|
||||
cmd = ['usermod', '-d', home]
|
||||
if persist:
|
||||
cmd += ' -m '
|
||||
cmd += name
|
||||
cmd.append('-m')
|
||||
cmd.append(name)
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['home'] != pre_info['home']:
|
||||
return post_info['home'] == home
|
||||
return False
|
||||
return info(name).get('home') == home
|
||||
|
||||
|
||||
def chgroups(name, groups, append=False):
|
||||
'''
|
||||
Change the groups this user belongs to, add append to append the specified
|
||||
Change the groups to which a user belongs
|
||||
|
||||
name
|
||||
Username to modify
|
||||
|
||||
groups
|
||||
List of groups to set for the user. Can be passed as a comma-separated
|
||||
list or a Python list.
|
||||
|
||||
append : False
|
||||
Set to ``True`` to append these groups to the user's existing list of
|
||||
groups. Otherwise, the specified groups will replace any existing
|
||||
groups for the user.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -276,15 +320,15 @@ def chgroups(name, groups, append=False):
|
||||
|
||||
salt '*' user.chgroups foo wheel,root True
|
||||
'''
|
||||
if isinstance(groups, string_types):
|
||||
if isinstance(groups, six.string_types):
|
||||
groups = groups.split(',')
|
||||
ugrps = set(list_groups(name))
|
||||
if ugrps == set(groups):
|
||||
return True
|
||||
if append:
|
||||
groups += ugrps
|
||||
cmd = 'usermod -G {0} {1} '.format(','.join(groups), name)
|
||||
return not __salt__['cmd.retcode'](cmd, python_shell=False)
|
||||
groups.update(ugrps)
|
||||
cmd = ['usermod', '-G', ','.join(groups), name]
|
||||
return __salt__['cmd.retcode'](cmd, python_shell=False) == 0
|
||||
|
||||
|
||||
def chfullname(name, fullname):
|
||||
@ -297,20 +341,7 @@ def chfullname(name, fullname):
|
||||
|
||||
salt '*' user.chfullname foo "Foo Bar"
|
||||
'''
|
||||
fullname = str(fullname)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if fullname == pre_info['fullname']:
|
||||
return True
|
||||
gecos_field = deepcopy(pre_info)
|
||||
gecos_field['fullname'] = fullname
|
||||
cmd = 'usermod -c "{0}" {1}'.format(_build_gecos(gecos_field), name)
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['fullname'] != pre_info['fullname']:
|
||||
return post_info['fullname'] == fullname
|
||||
return False
|
||||
return _update_gecos(name, 'fullname', fullname)
|
||||
|
||||
|
||||
def chroomnumber(name, roomnumber):
|
||||
@ -323,20 +354,7 @@ def chroomnumber(name, roomnumber):
|
||||
|
||||
salt '*' user.chroomnumber foo 123
|
||||
'''
|
||||
roomnumber = str(roomnumber)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if roomnumber == pre_info['roomnumber']:
|
||||
return True
|
||||
gecos_field = deepcopy(pre_info)
|
||||
gecos_field['roomnumber'] = roomnumber
|
||||
cmd = 'usermod -c "{0}" {1}'.format(_build_gecos(gecos_field), name)
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['roomnumber'] != pre_info['roomnumber']:
|
||||
return post_info['roomnumber'] == roomnumber
|
||||
return False
|
||||
return _update_gecos(name, 'roomnumber', roomnumber)
|
||||
|
||||
|
||||
def chworkphone(name, workphone):
|
||||
@ -349,20 +367,7 @@ def chworkphone(name, workphone):
|
||||
|
||||
salt '*' user.chworkphone foo "7735550123"
|
||||
'''
|
||||
workphone = str(workphone)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if workphone == pre_info['workphone']:
|
||||
return True
|
||||
gecos_field = deepcopy(pre_info)
|
||||
gecos_field['workphone'] = workphone
|
||||
cmd = 'usermod -c "{0}" {1}'.format(_build_gecos(gecos_field), name)
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['workphone'] != pre_info['workphone']:
|
||||
return post_info['workphone'] == workphone
|
||||
return False
|
||||
return _update_gecos(name, 'workphone', workphone)
|
||||
|
||||
|
||||
def chhomephone(name, homephone):
|
||||
@ -375,20 +380,7 @@ def chhomephone(name, homephone):
|
||||
|
||||
salt '*' user.chhomephone foo "7735551234"
|
||||
'''
|
||||
homephone = str(homephone)
|
||||
pre_info = _get_gecos(name)
|
||||
if not pre_info:
|
||||
return False
|
||||
if homephone == pre_info['homephone']:
|
||||
return True
|
||||
gecos_field = deepcopy(pre_info)
|
||||
gecos_field['homephone'] = homephone
|
||||
cmd = 'usermod -c "{0}" {1}'.format(_build_gecos(gecos_field), name)
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
post_info = info(name)
|
||||
if post_info['homephone'] != pre_info['homephone']:
|
||||
return post_info['homephone'] == homephone
|
||||
return False
|
||||
return _update_gecos(name, 'homephone', homephone)
|
||||
|
||||
|
||||
def info(name):
|
||||
@ -450,13 +442,12 @@ def rename(name, new_name):
|
||||
'''
|
||||
current_info = info(name)
|
||||
if not current_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
new_info = info(new_name)
|
||||
if new_info:
|
||||
raise CommandExecutionError('User {0!r} already exists'.format(new_name))
|
||||
cmd = 'usermod -l {0} {1}'.format(new_name, name)
|
||||
__salt__['cmd.run'](cmd)
|
||||
post_info = info(new_name)
|
||||
if post_info['name'] != current_info['name']:
|
||||
return post_info['name'] == new_name
|
||||
return False
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' already exists'.format(new_name)
|
||||
)
|
||||
cmd = ['usermod', '-l', new_name, name]
|
||||
__salt__['cmd.run'](cmd, python_shell=False)
|
||||
return info(new_name).get('name') == new_name
|
||||
|
@ -64,7 +64,7 @@ def _refine_enc(enc):
|
||||
return 'ssh-ed25519'
|
||||
else:
|
||||
raise CommandExecutionError(
|
||||
'Incorrect encryption key type {0!r}.'.format(enc)
|
||||
'Incorrect encryption key type \'{0}\'.'.format(enc)
|
||||
)
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ def _get_config_file(user, config):
|
||||
'''
|
||||
uinfo = __salt__['user.info'](user)
|
||||
if not uinfo:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(user))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(user))
|
||||
home = uinfo['home']
|
||||
if not os.path.isabs(config):
|
||||
config = os.path.join(home, config)
|
||||
@ -751,8 +751,9 @@ def get_known_host(user, hostname, config=None, port=None):
|
||||
return full
|
||||
|
||||
ssh_hostname = _hostname_and_port_to_ssh_hostname(hostname, port)
|
||||
cmd = 'ssh-keygen -F "{0}" -f "{1}"'.format(ssh_hostname, full)
|
||||
lines = __salt__['cmd.run'](cmd, ignore_retcode=True,
|
||||
cmd = ['ssh-keygen', '-F', ssh_hostname, '-f', full]
|
||||
lines = __salt__['cmd.run'](cmd,
|
||||
ignore_retcode=True,
|
||||
python_shell=False).splitlines()
|
||||
known_hosts = list(_parse_openssh_output(lines))
|
||||
return known_hosts[0] if known_hosts else None
|
||||
@ -771,19 +772,18 @@ def recv_known_host(hostname, enc=None, port=None, hash_hostname=False):
|
||||
'''
|
||||
# The following list of OSes have an old version of openssh-clients
|
||||
# and thus require the '-t' option for ssh-keyscan
|
||||
need_dash_t = ['CentOS-5']
|
||||
need_dash_t = ('CentOS-5',)
|
||||
|
||||
chunks = ['ssh-keyscan']
|
||||
cmd = ['ssh-keyscan']
|
||||
if port:
|
||||
chunks += ['-p', str(port)]
|
||||
cmd.extend(['-p', port])
|
||||
if enc:
|
||||
chunks += ['-t', str(enc)]
|
||||
cmd.extend(['-t', enc])
|
||||
if not enc and __grains__.get('osfinger') in need_dash_t:
|
||||
chunks += ['-t', 'rsa']
|
||||
cmd.extend(['-t', 'rsa'])
|
||||
if hash_hostname:
|
||||
chunks.append('-H')
|
||||
chunks.append(str(hostname))
|
||||
cmd = ' '.join(chunks)
|
||||
cmd.append('-H')
|
||||
cmd.append(hostname)
|
||||
lines = __salt__['cmd.run'](cmd, python_shell=False).splitlines()
|
||||
known_hosts = list(_parse_openssh_output(lines))
|
||||
return known_hosts[0] if known_hosts else None
|
||||
@ -854,7 +854,7 @@ def rm_known_host(user=None, hostname=None, config=None, port=None):
|
||||
'error': 'Known hosts file {0} does not exist'.format(full)}
|
||||
|
||||
ssh_hostname = _hostname_and_port_to_ssh_hostname(hostname, port)
|
||||
cmd = 'ssh-keygen -R "{0}" -f "{1}"'.format(ssh_hostname, full)
|
||||
cmd = ['ssh-keygen', '-R', ssh_hostname, '-f', full]
|
||||
cmd_result = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
# ssh-keygen creates a new file, thus a chown is required.
|
||||
if os.geteuid() == 0 and user:
|
||||
@ -1139,7 +1139,7 @@ def hash_known_hosts(user=None, config=None):
|
||||
if not os.path.isfile(full):
|
||||
return {'status': 'error',
|
||||
'error': 'Known hosts file {0} does not exist'.format(full)}
|
||||
cmd = 'ssh-keygen -H -f "{0}"'.format(full)
|
||||
cmd = ['ssh-keygen', '-H', '-f', full]
|
||||
cmd_result = __salt__['cmd.run'](cmd, python_shell=False)
|
||||
# ssh-keygen creates a new file, thus a chown is required.
|
||||
if os.geteuid() == 0 and user:
|
||||
|
@ -59,7 +59,7 @@ def _ctl_cmd(cmd, name, conf_file, bin_env):
|
||||
ret.append(cmd)
|
||||
if name:
|
||||
ret.append(name)
|
||||
return ' ' .join(ret)
|
||||
return ret
|
||||
|
||||
|
||||
def _get_return(ret):
|
||||
@ -395,7 +395,7 @@ def options(name, conf_file=None):
|
||||
config = _read_config(conf_file)
|
||||
section_name = 'program:{0}'.format(name)
|
||||
if section_name not in config.sections():
|
||||
raise CommandExecutionError('Process {0!r} not found'.format(name))
|
||||
raise CommandExecutionError('Process \'{0}\' not found'.format(name))
|
||||
ret = {}
|
||||
for key, val in config.items(section_name):
|
||||
val = salt.utils.str_to_num(val.split(';')[0].strip())
|
||||
|
@ -59,8 +59,8 @@ __func_alias__ = {
|
||||
'reload_': 'reload'
|
||||
}
|
||||
|
||||
_INDENT = ""
|
||||
_INDENT_STEP = " "
|
||||
_INDENT = ''
|
||||
_INDENT_STEP = ' '
|
||||
|
||||
# These are needed during building of the configuration tree
|
||||
_current_statement = None
|
||||
@ -89,14 +89,14 @@ def _indent(value):
|
||||
'''
|
||||
Returns the indented parameter.
|
||||
'''
|
||||
return "{0}{1}".format(_INDENT, value)
|
||||
return '{0}{1}'.format(_INDENT, value)
|
||||
|
||||
|
||||
def _indentln(string):
|
||||
'''
|
||||
Return the indented parameter with newline.
|
||||
'''
|
||||
return _indent(string + "\n")
|
||||
return _indent(string + '\n')
|
||||
|
||||
|
||||
class Buildable(object):
|
||||
@ -132,7 +132,7 @@ class Buildable(object):
|
||||
_increase_indent()
|
||||
body_array = [x.build() for x in self.iterable]
|
||||
|
||||
nl = "\n" if self.append_extra_newline else ''
|
||||
nl = '\n' if self.append_extra_newline else ''
|
||||
|
||||
if len(self.iterable) >= 1:
|
||||
body = self.join_body_on.join(body_array) + nl
|
||||
@ -162,7 +162,9 @@ class Statement(Buildable):
|
||||
'''
|
||||
|
||||
def __init__(self, type, id='', options=None, has_name=True):
|
||||
super(Statement, self).__init__(options, join_body_on='', append_extra_newline=False)
|
||||
super(Statement, self).__init__(options,
|
||||
join_body_on='',
|
||||
append_extra_newline=False)
|
||||
self.type = type
|
||||
self.id = id
|
||||
self.options = options if options else []
|
||||
@ -171,12 +173,12 @@ class Statement(Buildable):
|
||||
|
||||
def build_header(self):
|
||||
if self.has_name:
|
||||
return _indentln("{0} {1} {{".format(self.type, self.id))
|
||||
return _indentln('{0} {1} {{'.format(self.type, self.id))
|
||||
else:
|
||||
return _indentln("{0} {{".format(self.type))
|
||||
return _indentln('{0} {{'.format(self.type))
|
||||
|
||||
def build_tail(self):
|
||||
return _indentln("};")
|
||||
return _indentln('};')
|
||||
|
||||
def add_child(self, option):
|
||||
self.options.append(option)
|
||||
@ -201,7 +203,10 @@ class UnnamedStatement(Statement):
|
||||
'''
|
||||
|
||||
def __init__(self, type, options=None):
|
||||
super(UnnamedStatement, self).__init__(type, id='', options=options, has_name=False)
|
||||
super(UnnamedStatement, self).__init__(type,
|
||||
id='',
|
||||
options=options,
|
||||
has_name=False)
|
||||
|
||||
|
||||
class GivenStatement(Buildable):
|
||||
@ -219,7 +224,7 @@ class GivenStatement(Buildable):
|
||||
|
||||
def build(self):
|
||||
if self.add_newline:
|
||||
return self.value + "\n"
|
||||
return self.value + '\n'
|
||||
else:
|
||||
return self.value
|
||||
|
||||
@ -234,14 +239,14 @@ class Option(Buildable):
|
||||
'''
|
||||
|
||||
def __init__(self, type='', params=None):
|
||||
super(Option, self).__init__(params, ",\n")
|
||||
super(Option, self).__init__(params, ',\n')
|
||||
self.type = type
|
||||
self.params = params if params else []
|
||||
self.iterable = self.params
|
||||
|
||||
def build(self):
|
||||
header = _indentln("{0}(".format(self.type))
|
||||
tail = _indentln(");")
|
||||
header = _indentln('{0}('.format(self.type))
|
||||
tail = _indentln(');')
|
||||
body = self.build_body()
|
||||
|
||||
return header + body + tail
|
||||
@ -263,7 +268,8 @@ class Parameter(Buildable):
|
||||
|
||||
class SimpleParameter(Parameter):
|
||||
'''
|
||||
A Parameter is a SimpleParameter, if it's just a simple type, like a string.
|
||||
A Parameter is a SimpleParameter, if it's just a simple type, like a
|
||||
string.
|
||||
|
||||
For example:
|
||||
|
||||
@ -271,7 +277,7 @@ class SimpleParameter(Parameter):
|
||||
|
||||
destination d_file {
|
||||
file(
|
||||
"/var/log/messages"
|
||||
'/var/log/messages'
|
||||
);
|
||||
};
|
||||
|
||||
@ -306,14 +312,14 @@ class TypedParameter(Parameter):
|
||||
'''
|
||||
|
||||
def __init__(self, type='', values=None):
|
||||
super(TypedParameter, self).__init__(values, ",\n")
|
||||
super(TypedParameter, self).__init__(values, ',\n')
|
||||
self.type = type
|
||||
self.values = values if values else []
|
||||
self.iterable = self.values
|
||||
|
||||
def build(self):
|
||||
header = _indentln("{0}(".format(self.type))
|
||||
tail = _indent(")")
|
||||
header = _indentln('{0}('.format(self.type))
|
||||
tail = _indent(')')
|
||||
body = self.build_body()
|
||||
|
||||
return header + body + tail
|
||||
@ -364,8 +370,8 @@ class TypedParameterValue(ParameterValue):
|
||||
ip(0.0.0.0)
|
||||
port(1999)
|
||||
tls(
|
||||
key_file("/opt/syslog-ng/etc/syslog-ng/key.d/syslog-ng.key")
|
||||
cert_file("/opt/syslog-ng/etc/syslog-ng/cert.d/syslog-ng.cert")
|
||||
key_file('/opt/syslog-ng/etc/syslog-ng/key.d/syslog-ng.key')
|
||||
cert_file('/opt/syslog-ng/etc/syslog-ng/cert.d/syslog-ng.cert')
|
||||
)
|
||||
);
|
||||
};
|
||||
@ -374,14 +380,14 @@ class TypedParameterValue(ParameterValue):
|
||||
'''
|
||||
|
||||
def __init__(self, type='', arguments=None):
|
||||
super(TypedParameterValue, self).__init__(arguments, "\n")
|
||||
super(TypedParameterValue, self).__init__(arguments, '\n')
|
||||
self.type = type
|
||||
self.arguments = arguments if arguments else []
|
||||
self.iterable = self.arguments
|
||||
|
||||
def build(self):
|
||||
header = _indentln("{0}(".format(self.type))
|
||||
tail = _indent(")")
|
||||
header = _indentln('{0}('.format(self.type))
|
||||
tail = _indent(')')
|
||||
body = self.build_body()
|
||||
|
||||
return header + body + tail
|
||||
@ -650,7 +656,7 @@ def config(name,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' syslog_ng.config name="s_local" config="[{'tcp':[{'ip':'127.0.0.1'},{'port':1233}]}]"
|
||||
salt '*' syslog_ng.config name='s_local' config="[{'tcp':[{'ip':'127.0.0.1'},{'port':1233}]}]"
|
||||
|
||||
'''
|
||||
|
||||
@ -658,14 +664,18 @@ def config(name,
|
||||
configs = _render_configuration()
|
||||
|
||||
if __opts__.get('test', False):
|
||||
comment = "State syslog_ng will write '{0}' into {1}".format(configs, __SYSLOG_NG_CONFIG_FILE)
|
||||
comment = 'State syslog_ng will write \'{0}\' into {1}'.format(
|
||||
configs,
|
||||
__SYSLOG_NG_CONFIG_FILE
|
||||
)
|
||||
return _format_state_result(name, result=None, comment=comment)
|
||||
|
||||
succ = write
|
||||
if write:
|
||||
succ = _write_config(config=configs)
|
||||
|
||||
return _format_state_result(name, result=succ, changes={'new': configs, 'old': ''})
|
||||
return _format_state_result(name, result=succ,
|
||||
changes={'new': configs, 'old': ''})
|
||||
|
||||
|
||||
def set_binary_path(name):
|
||||
@ -680,7 +690,7 @@ def set_binary_path(name):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' syslog_ng.set_binary_path name="/usr/sbin"
|
||||
salt '*' syslog_ng.set_binary_path name=/usr/sbin
|
||||
|
||||
'''
|
||||
global __SYSLOG_NG_BINARY_PATH
|
||||
@ -692,13 +702,14 @@ def set_binary_path(name):
|
||||
|
||||
def set_config_file(name):
|
||||
'''
|
||||
Sets the configuration's name. This function is intended to be used from states.
|
||||
Sets the configuration's name. This function is intended to be used from
|
||||
states.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' syslog_ng.set_config_file name="/etc/syslog-ng"
|
||||
salt '*' syslog_ng.set_config_file name=/etc/syslog-ng
|
||||
|
||||
'''
|
||||
global __SYSLOG_NG_CONFIG_FILE
|
||||
@ -724,19 +735,12 @@ def get_config_file():
|
||||
|
||||
def _run_command(cmd, options=()):
|
||||
'''
|
||||
Runs the command cmd with options as its CLI parameters and returns the result
|
||||
as a dictionary.
|
||||
Runs the command cmd with options as its CLI parameters and returns the
|
||||
result as a dictionary.
|
||||
'''
|
||||
cmd_with_params = [cmd]
|
||||
cmd_with_params.extend(options)
|
||||
|
||||
cmd_to_run = " ".join(cmd_with_params)
|
||||
|
||||
try:
|
||||
return __salt__['cmd.run_all'](cmd_to_run)
|
||||
except Exception as err:
|
||||
log.error(str(err))
|
||||
raise CommandExecutionError("Unable to run command: " + str(type(err)))
|
||||
params = [cmd]
|
||||
params.extend(options)
|
||||
return __salt__['cmd.run_all'](params, python_shell=False)
|
||||
|
||||
|
||||
def _determine_config_version(syslog_ng_sbin_dir):
|
||||
@ -764,8 +768,8 @@ def set_parameters(version=None,
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' syslog_ng.set_parameters version="3.6"
|
||||
salt '*' syslog_ng.set_parameters binary_path="/home/user/install/syslog-ng/sbin" config_file="/home/user/install/syslog-ng/etc/syslog-ng.conf"
|
||||
salt '*' syslog_ng.set_parameters version='3.6'
|
||||
salt '*' syslog_ng.set_parameters binary_path=/home/user/install/syslog-ng/sbin config_file=/home/user/install/syslog-ng/etc/syslog-ng.conf
|
||||
|
||||
'''
|
||||
if binary_path:
|
||||
@ -787,10 +791,11 @@ def _add_to_path_envvar(directory):
|
||||
orig_path = os.environ.get('PATH', '')
|
||||
if directory:
|
||||
if not os.path.isdir(directory):
|
||||
log.error("The given parameter is not a directory")
|
||||
|
||||
os.environ["PATH"] = "{0}{1}{2}".format(orig_path, os.pathsep, directory)
|
||||
log.error('The given parameter is not a directory')
|
||||
|
||||
os.environ['PATH'] = '{0}{1}{2}'.format(orig_path,
|
||||
os.pathsep,
|
||||
directory)
|
||||
return orig_path
|
||||
|
||||
|
||||
@ -799,7 +804,7 @@ def _restore_path_envvar(original):
|
||||
Sets the PATH environment variable to the parameter.
|
||||
'''
|
||||
if original:
|
||||
os.environ["PATH"] = original
|
||||
os.environ['PATH'] = original
|
||||
|
||||
|
||||
def _run_command_in_extended_path(syslog_ng_sbin_dir, command, params):
|
||||
@ -810,7 +815,10 @@ def _run_command_in_extended_path(syslog_ng_sbin_dir, command, params):
|
||||
orig_path = _add_to_path_envvar(syslog_ng_sbin_dir)
|
||||
|
||||
if not salt.utils.which(command):
|
||||
error_message = "Unable to execute the command '{0}'. It is not in the PATH.".format(command)
|
||||
error_message = (
|
||||
'Unable to execute the command \'{0}\'. It is not in the PATH.'
|
||||
.format(command)
|
||||
)
|
||||
log.error(error_message)
|
||||
_restore_path_envvar(orig_path)
|
||||
raise CommandExecutionError(error_message)
|
||||
@ -825,11 +833,11 @@ def _format_return_data(retcode, stdout=None, stderr=None):
|
||||
Creates a dictionary from the parameters, which can be used to return data
|
||||
to Salt.
|
||||
'''
|
||||
ret = {"retcode": retcode}
|
||||
ret = {'retcode': retcode}
|
||||
if stdout is not None:
|
||||
ret["stdout"] = stdout
|
||||
ret['stdout'] = stdout
|
||||
if stderr is not None:
|
||||
ret["stderr"] = stderr
|
||||
ret['stderr'] = stderr
|
||||
return ret
|
||||
|
||||
|
||||
@ -846,25 +854,28 @@ def config_test(syslog_ng_sbin_dir=None, cfgfile=None):
|
||||
salt '*' syslog_ng.config_test /home/user/install/syslog-ng/sbin
|
||||
salt '*' syslog_ng.config_test /home/user/install/syslog-ng/sbin /etc/syslog-ng/syslog-ng.conf
|
||||
'''
|
||||
params = ["--syntax-only", ]
|
||||
params = ['--syntax-only']
|
||||
if cfgfile:
|
||||
params.append("--cfgfile={0}".format(cfgfile))
|
||||
params.append('--cfgfile={0}'.format(cfgfile))
|
||||
|
||||
try:
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir, "syslog-ng", params)
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir,
|
||||
'syslog-ng',
|
||||
params)
|
||||
except CommandExecutionError as err:
|
||||
return _format_return_data(retcode=-1, stderr=str(err))
|
||||
|
||||
retcode = ret.get("retcode", -1)
|
||||
stderr = ret.get("stderr", None)
|
||||
stdout = ret.get("stdout", None)
|
||||
retcode = ret.get('retcode', -1)
|
||||
stderr = ret.get('stderr', None)
|
||||
stdout = ret.get('stdout', None)
|
||||
return _format_return_data(retcode, stdout, stderr)
|
||||
|
||||
|
||||
def version(syslog_ng_sbin_dir=None):
|
||||
'''
|
||||
Returns the version of the installed syslog-ng. If syslog_ng_sbin_dir is specified, it
|
||||
is added to the PATH during the execution of the command syslog-ng.
|
||||
Returns the version of the installed syslog-ng. If syslog_ng_sbin_dir is
|
||||
specified, it is added to the PATH during the execution of the command
|
||||
syslog-ng.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -874,14 +885,18 @@ def version(syslog_ng_sbin_dir=None):
|
||||
salt '*' syslog_ng.version /home/user/install/syslog-ng/sbin
|
||||
'''
|
||||
try:
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir, "syslog-ng", ("-V",))
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir,
|
||||
'syslog-ng',
|
||||
('-V',))
|
||||
except CommandExecutionError as err:
|
||||
return _format_return_data(retcode=-1, stderr=str(err))
|
||||
|
||||
if ret["retcode"] != 0:
|
||||
return _format_return_data(ret["retcode"], stderr=ret["stderr"], stdout=ret["stdout"])
|
||||
if ret['retcode'] != 0:
|
||||
return _format_return_data(ret['retcode'],
|
||||
stderr=ret['stderr'],
|
||||
stdout=ret['stdout'])
|
||||
|
||||
lines = ret["stdout"].split("\n")
|
||||
lines = ret['stdout'].split('\n')
|
||||
# The format of the first line in the output is:
|
||||
# syslog-ng 3.6.0alpha0
|
||||
version_line_index = 0
|
||||
@ -903,25 +918,31 @@ def modules(syslog_ng_sbin_dir=None):
|
||||
salt '*' syslog_ng.modules /home/user/install/syslog-ng/sbin
|
||||
'''
|
||||
try:
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir, "syslog-ng", ("-V",))
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir,
|
||||
'syslog-ng',
|
||||
('-V',))
|
||||
except CommandExecutionError as err:
|
||||
return _format_return_data(retcode=-1, stderr=str(err))
|
||||
|
||||
if ret["retcode"] != 0:
|
||||
return _format_return_data(ret["retcode"], ret.get("stdout", None), ret.get("stderr", None))
|
||||
if ret['retcode'] != 0:
|
||||
return _format_return_data(ret['retcode'],
|
||||
ret.get('stdout'),
|
||||
ret.get('stderr'))
|
||||
|
||||
lines = ret["stdout"].split("\n")
|
||||
lines = ret['stdout'].split('\n')
|
||||
for line in lines:
|
||||
if line.startswith("Available-Modules"):
|
||||
if line.startswith('Available-Modules'):
|
||||
label, installed_modules = line.split()
|
||||
return _format_return_data(ret["retcode"], stdout=installed_modules)
|
||||
return _format_return_data(-1, stderr="Unable to find the modules.")
|
||||
return _format_return_data(ret['retcode'],
|
||||
stdout=installed_modules)
|
||||
return _format_return_data(-1, stderr='Unable to find the modules.')
|
||||
|
||||
|
||||
def stats(syslog_ng_sbin_dir=None):
|
||||
'''
|
||||
Returns statistics from the running syslog-ng instance. If syslog_ng_sbin_dir is specified, it
|
||||
is added to the PATH during the execution of the command syslog-ng-ctl.
|
||||
Returns statistics from the running syslog-ng instance. If
|
||||
syslog_ng_sbin_dir is specified, it is added to the PATH during the
|
||||
execution of the command syslog-ng-ctl.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -931,11 +952,15 @@ def stats(syslog_ng_sbin_dir=None):
|
||||
salt '*' syslog_ng.stats /home/user/install/syslog-ng/sbin
|
||||
'''
|
||||
try:
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir, "syslog-ng-ctl", ("stats",))
|
||||
ret = _run_command_in_extended_path(syslog_ng_sbin_dir,
|
||||
'syslog-ng-ctl',
|
||||
('stats',))
|
||||
except CommandExecutionError as err:
|
||||
return _format_return_data(retcode=-1, stderr=str(err))
|
||||
|
||||
return _format_return_data(ret["retcode"], ret.get("stdout", None), ret.get("stderr", None))
|
||||
return _format_return_data(ret['retcode'],
|
||||
ret.get('stdout'),
|
||||
ret.get('stderr'))
|
||||
|
||||
|
||||
def _format_changes(old='', new=''):
|
||||
@ -948,7 +973,8 @@ def _format_state_result(name, result, changes=None, comment=''):
|
||||
'''
|
||||
if changes is None:
|
||||
changes = {'old': '', 'new': ''}
|
||||
return {'name': name, 'result': result, 'changes': changes, 'comment': comment}
|
||||
return {'name': name, 'result': result,
|
||||
'changes': changes, 'comment': comment}
|
||||
|
||||
|
||||
def _add_cli_param(params, key, value):
|
||||
@ -972,8 +998,9 @@ def stop(name=None):
|
||||
Kills syslog-ng. This function is intended to be used from the state module.
|
||||
|
||||
Users shouldn't use this function, if the service module is available on
|
||||
their system. If :mod:`syslog_ng.set_config_file <salt.modules.syslog_ng.set_binary_path>`
|
||||
is called before, this function will use the set binary path.
|
||||
their system. If :mod:`syslog_ng.set_config_file
|
||||
<salt.modules.syslog_ng.set_binary_path>` is called before, this function
|
||||
will use the set binary path.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -990,7 +1017,7 @@ def stop(name=None):
|
||||
comment='Syslog-ng is not running')
|
||||
|
||||
if __opts__.get('test', False):
|
||||
comment = "Syslog_ng state module will kill {0} pids"
|
||||
comment = 'Syslog_ng state module will kill {0} pids'
|
||||
return _format_state_result(name, result=None, comment=comment)
|
||||
|
||||
res = __salt__['ps.pkill']('syslog-ng')
|
||||
@ -1024,8 +1051,9 @@ def start(name=None,
|
||||
is intended to be used from the state module.
|
||||
|
||||
Users shouldn't use this function, if the service module is available on
|
||||
their system. If :mod:`syslog_ng.set_config_file <salt.modules.syslog_ng.set_binary_path>`,
|
||||
is called before, this function will use the set binary path.
|
||||
their system. If :mod:`syslog_ng.set_config_file
|
||||
<salt.modules.syslog_ng.set_binary_path>`, is called before, this function
|
||||
will use the set binary path.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -1051,24 +1079,23 @@ def start(name=None,
|
||||
_add_boolean_cli_param(params, 'persist-file', persist_file)
|
||||
_add_cli_param(params, 'control', control)
|
||||
_add_cli_param(params, 'worker-threads', worker_threads)
|
||||
cli_params = ' '.join(params)
|
||||
if __SYSLOG_NG_BINARY_PATH:
|
||||
syslog_ng_binary = os.path.join(__SYSLOG_NG_BINARY_PATH, 'syslog-ng')
|
||||
command = syslog_ng_binary + ' ' + cli_params
|
||||
command = [syslog_ng_binary] + params
|
||||
|
||||
if __opts__.get('test', False):
|
||||
comment = "Syslog_ng state module will start {0}".format(command)
|
||||
comment = 'Syslog_ng state module will start {0}'.format(command)
|
||||
return _format_state_result(name, result=None, comment=comment)
|
||||
|
||||
result = __salt__['cmd.run_all'](command)
|
||||
result = __salt__['cmd.run_all'](command, python_shell=False)
|
||||
else:
|
||||
command = 'syslog-ng ' + cli_params
|
||||
command = ['syslog-ng'] + params
|
||||
|
||||
if __opts__.get('test', False):
|
||||
comment = "Syslog_ng state module will start {0}".format(command)
|
||||
comment = 'Syslog_ng state module will start {0}'.format(command)
|
||||
return _format_state_result(name, result=None, comment=comment)
|
||||
|
||||
result = __salt__['cmd.run_all'](command)
|
||||
result = __salt__['cmd.run_all'](command, python_shell=False)
|
||||
|
||||
if result['pid'] > 0:
|
||||
succ = True
|
||||
@ -1076,7 +1103,7 @@ def start(name=None,
|
||||
succ = False
|
||||
|
||||
return _format_state_result(
|
||||
name, result=succ, changes={'new': command, 'old': ''}
|
||||
name, result=succ, changes={'new': ' '.join(command), 'old': ''}
|
||||
)
|
||||
|
||||
|
||||
@ -1084,8 +1111,9 @@ def reload_(name):
|
||||
'''
|
||||
Reloads syslog-ng. This function is intended to be used from states.
|
||||
|
||||
If :mod:`syslog_ng.set_config_file <salt.modules.syslog_ng.set_binary_path>`,
|
||||
is called before, this function will use the set binary path.
|
||||
If :mod:`syslog_ng.set_config_file
|
||||
<salt.modules.syslog_ng.set_binary_path>`, is called before, this function
|
||||
will use the set binary path.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -1095,12 +1123,13 @@ def reload_(name):
|
||||
|
||||
'''
|
||||
if __SYSLOG_NG_BINARY_PATH:
|
||||
syslog_ng_ctl_binary = os.path.join(__SYSLOG_NG_BINARY_PATH, 'syslog-ng-ctl')
|
||||
command = syslog_ng_ctl_binary + ' reload'
|
||||
result = __salt__['cmd.run_all'](command)
|
||||
syslog_ng_ctl_binary = os.path.join(__SYSLOG_NG_BINARY_PATH,
|
||||
'syslog-ng-ctl')
|
||||
command = [syslog_ng_ctl_binary, 'reload']
|
||||
result = __salt__['cmd.run_all'](command, python_shell=False)
|
||||
else:
|
||||
command = 'syslog-ng-ctl reload'
|
||||
result = __salt__['cmd.run_all'](command)
|
||||
command = ['syslog-ng-ctl', 'reload']
|
||||
result = __salt__['cmd.run_all'](command, python_shell=False)
|
||||
|
||||
succ = True if result['retcode'] == 0 else False
|
||||
return _format_state_result(name, result=succ, comment=result['stdout'])
|
||||
@ -1119,14 +1148,15 @@ def write_config(config, newlines=2):
|
||||
Writes the given parameter config into the config file. This function is
|
||||
intended to be used from states.
|
||||
|
||||
If :mod:`syslog_ng.set_config_file <salt.modules.syslog_ng.set_config_file>`,
|
||||
is called before, this function will use the set config file.
|
||||
If :mod:`syslog_ng.set_config_file
|
||||
<salt.modules.syslog_ng.set_config_file>`, is called before, this function
|
||||
will use the set config file.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' syslog_ng.write_config config="# comment"
|
||||
salt '*' syslog_ng.write_config config='# comment'
|
||||
|
||||
'''
|
||||
succ = _write_config(config, newlines)
|
||||
@ -1157,11 +1187,12 @@ def _write_config(config, newlines=2):
|
||||
|
||||
def write_version(name):
|
||||
'''
|
||||
Removes the previous configuration file, then creates a new one and writes the name line.
|
||||
This function is intended to be used from states.
|
||||
Removes the previous configuration file, then creates a new one and writes
|
||||
the name line. This function is intended to be used from states.
|
||||
|
||||
If :mod:`syslog_ng.set_config_file <salt.modules.syslog_ng.set_config_file>`,
|
||||
is called before, this function will use the set config file.
|
||||
If :mod:`syslog_ng.set_config_file
|
||||
<salt.modules.syslog_ng.set_config_file>`, is called before, this function
|
||||
will use the set config file.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -1174,7 +1205,9 @@ def write_version(name):
|
||||
try:
|
||||
if os.path.exists(__SYSLOG_NG_CONFIG_FILE):
|
||||
log.debug(
|
||||
'Removing previous configuration file: {0}'.format(__SYSLOG_NG_CONFIG_FILE)
|
||||
'Removing previous configuration file: {0}'.format(
|
||||
__SYSLOG_NG_CONFIG_FILE
|
||||
)
|
||||
)
|
||||
os.remove(__SYSLOG_NG_CONFIG_FILE)
|
||||
log.debug('Configuration file successfully removed')
|
||||
@ -1184,9 +1217,9 @@ def write_version(name):
|
||||
_write_config(config=line, newlines=2)
|
||||
|
||||
return _format_state_result(name, result=True)
|
||||
except os.error as err:
|
||||
except OSError as err:
|
||||
log.error(
|
||||
'Failed to remove previous configuration file {0!r} because: {1}'
|
||||
'Failed to remove previous configuration file \'{0}\': {1}'
|
||||
.format(__SYSLOG_NG_CONFIG_FILE, str(err))
|
||||
)
|
||||
return _format_state_result(name, result=False)
|
||||
|
@ -13,6 +13,7 @@ import string
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
from salt.exceptions import SaltInvocationError, CommandExecutionError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@ -101,7 +102,7 @@ def get_zone():
|
||||
cmd = ''
|
||||
if salt.utils.which('timedatectl'):
|
||||
out = __salt__['cmd.run'](['timedatectl'], python_shell=False)
|
||||
for line in (x.strip() for x in out.splitlines()):
|
||||
for line in (x.strip() for x in salt.utils.itertools.split(out, '\n')):
|
||||
try:
|
||||
return re.match(r'Time ?zone:\s+(\S+)', line).group(1)
|
||||
except AttributeError:
|
||||
@ -237,7 +238,7 @@ def zone_compare(timezone):
|
||||
try:
|
||||
usrzone = salt.utils.get_hash(zonepath, hash_type)
|
||||
except IOError as exc:
|
||||
raise SaltInvocationError('Invalid timezone {0!r}'.format(timezone))
|
||||
raise SaltInvocationError('Invalid timezone \'{0}\''.format(timezone))
|
||||
|
||||
try:
|
||||
etczone = salt.utils.get_hash(tzfile, hash_type)
|
||||
|
@ -9,11 +9,10 @@ import glob
|
||||
import shutil
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.exceptions
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
from salt.ext.six import string_types
|
||||
|
||||
KNOWN_BINARY_NAMES = frozenset(
|
||||
@ -40,6 +39,20 @@ def __virtual__():
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def _not_a_virtualenv(path):
|
||||
raise CommandExecutionError(
|
||||
'Path \'{0}\' does not appear to be a virtualenv'.format(path)
|
||||
)
|
||||
|
||||
|
||||
def _verify_safe_py_code(*args):
|
||||
for arg in args:
|
||||
if not salt.utils.verify.safe_py_code(arg):
|
||||
raise SaltInvocationError(
|
||||
'Unsafe python code detected in \'{0}\''.format(arg)
|
||||
)
|
||||
|
||||
|
||||
def create(path,
|
||||
venv_bin=None,
|
||||
system_site_packages=False,
|
||||
@ -59,42 +72,56 @@ def create(path,
|
||||
Create a virtualenv
|
||||
|
||||
path
|
||||
The path to create the virtualenv
|
||||
venv_bin : None (default 'virtualenv')
|
||||
The path to the virtualenv to be created
|
||||
|
||||
venv_bin
|
||||
The name (and optionally path) of the virtualenv command. This can also
|
||||
be set globally in the minion config file as ``virtualenv.venv_bin``.
|
||||
Defaults to ``virtualenv``.
|
||||
|
||||
system_site_packages : False
|
||||
Passthrough argument given to virtualenv or pyvenv
|
||||
|
||||
distribute : False
|
||||
Passthrough argument given to virtualenv
|
||||
|
||||
pip : False
|
||||
Install pip after creating a virtual environment,
|
||||
implies distribute=True
|
||||
Install pip after creating a virtual environment. Implies
|
||||
``distribute=True``
|
||||
|
||||
clear : False
|
||||
Passthrough argument given to virtualenv or pyvenv
|
||||
|
||||
python : None (default)
|
||||
Passthrough argument given to virtualenv
|
||||
|
||||
extra_search_dir : None (default)
|
||||
Passthrough argument given to virtualenv
|
||||
|
||||
never_download : None (default)
|
||||
Passthrough argument given to virtualenv if True
|
||||
|
||||
prompt : None (default)
|
||||
Passthrough argument given to virtualenv if not None
|
||||
|
||||
symlinks : None
|
||||
Passthrough argument given to pyvenv if True
|
||||
|
||||
upgrade : None
|
||||
Passthrough argument given to pyvenv if True
|
||||
|
||||
user : None
|
||||
Set ownership for the virtualenv
|
||||
|
||||
runas : None
|
||||
Set ownership for the virtualenv
|
||||
|
||||
.. deprecated:: 2014.1.0
|
||||
``user`` should be used instead
|
||||
|
||||
use_vt
|
||||
Use VT terminal emulation (see ouptut while installing)
|
||||
|
||||
.. note::
|
||||
The ``runas`` argument is deprecated as of 2014.1.0. ``user`` should be
|
||||
used instead.
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
@ -113,14 +140,14 @@ def create(path,
|
||||
# If any of the following values are not None, it means that the user
|
||||
# is actually passing a True or False value. Stop Him!
|
||||
if upgrade is not None:
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'The `upgrade`(`--upgrade`) option is not supported '
|
||||
'by {0!r}'.format(venv_bin)
|
||||
'by \'{0}\''.format(venv_bin)
|
||||
)
|
||||
elif symlinks is not None:
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'The `symlinks`(`--symlinks`) option is not supported '
|
||||
'by {0!r}'.format(venv_bin)
|
||||
'by \'{0}\''.format(venv_bin)
|
||||
)
|
||||
# <---- Stop the user if pyvenv only options are used ----------------
|
||||
|
||||
@ -134,14 +161,14 @@ def create(path,
|
||||
)
|
||||
except ImportError:
|
||||
# Unable to import?? Let's parse the version from the console
|
||||
version_cmd = '{0} --version'.format(venv_bin)
|
||||
version_cmd = [venv_bin, '--version']
|
||||
ret = __salt__['cmd.run_all'](
|
||||
version_cmd, runas=user, python_shell=False
|
||||
)
|
||||
if ret['retcode'] > 0 or not ret['stdout'].strip():
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
'Unable to get the virtualenv version output using {0!r}. '
|
||||
'Returned data: {1!r}'.format(version_cmd, ret)
|
||||
raise CommandExecutionError(
|
||||
'Unable to get the virtualenv version output using \'{0}\'. '
|
||||
'Returned data: {1}'.format(version_cmd, ret)
|
||||
)
|
||||
virtualenv_version_info = tuple(
|
||||
[int(i) for i in
|
||||
@ -161,7 +188,7 @@ def create(path,
|
||||
|
||||
if python is not None and python.strip() != '':
|
||||
if not salt.utils.which(python):
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'Cannot find requested python ({0}).'.format(python)
|
||||
)
|
||||
cmd.append('--python={0}'.format(python))
|
||||
@ -184,7 +211,7 @@ def create(path,
|
||||
else:
|
||||
cmd.append('--never-download')
|
||||
if prompt is not None and prompt.strip() != '':
|
||||
cmd.append('--prompt={0!r}'.format(prompt))
|
||||
cmd.append('--prompt=\'{0}\''.format(prompt))
|
||||
else:
|
||||
# venv module from the Python >= 3.3 standard library
|
||||
|
||||
@ -192,24 +219,24 @@ def create(path,
|
||||
# If any of the following values are not None, it means that the user
|
||||
# is actually passing a True or False value. Stop Him!
|
||||
if python is not None and python.strip() != '':
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'The `python`(`--python`) option is not supported '
|
||||
'by {0!r}'.format(venv_bin)
|
||||
'by \'{0}\''.format(venv_bin)
|
||||
)
|
||||
elif extra_search_dir is not None and extra_search_dir.strip() != '':
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'The `extra_search_dir`(`--extra-search-dir`) option is not '
|
||||
'supported by {0!r}'.format(venv_bin)
|
||||
'supported by \'{0}\''.format(venv_bin)
|
||||
)
|
||||
elif never_download is not None:
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'The `never_download`(`--never-download`) option is not '
|
||||
'supported by {0!r}'.format(venv_bin)
|
||||
'supported by \'{0}\''.format(venv_bin)
|
||||
)
|
||||
elif prompt is not None and prompt.strip() != '':
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
raise CommandExecutionError(
|
||||
'The `prompt`(`--prompt`) option is not supported '
|
||||
'by {0!r}'.format(venv_bin)
|
||||
'by \'{0}\''.format(venv_bin)
|
||||
)
|
||||
# <---- Stop the user if virtualenv only options are being used ------
|
||||
|
||||
@ -290,12 +317,16 @@ def get_site_packages(venv):
|
||||
'''
|
||||
bin_path = os.path.join(venv, 'bin/python')
|
||||
if not os.path.exists(bin_path):
|
||||
raise salt.exceptions.CommandExecutionError("Path does not appear to be a virtualenv: '{0}'".format(venv))
|
||||
_not_a_virtualenv(venv)
|
||||
|
||||
ret = __salt__['cmd.exec_code_all'](bin_path, 'from distutils import sysconfig; print sysconfig.get_python_lib()')
|
||||
ret = __salt__['cmd.exec_code_all'](
|
||||
bin_path,
|
||||
'from distutils import sysconfig; '
|
||||
'print sysconfig.get_python_lib()'
|
||||
)
|
||||
|
||||
if ret['retcode'] != 0:
|
||||
raise salt.exceptions.CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
raise CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
|
||||
return ret['stdout']
|
||||
|
||||
@ -318,37 +349,59 @@ def get_distribution_path(venv, distribution):
|
||||
|
||||
salt '*' virtualenv.get_distribution_path /path/to/my/venv my_distribution
|
||||
'''
|
||||
if not salt.utils.verify.safe_py_code(distribution):
|
||||
raise salt.exceptions.CommandExecutionError
|
||||
_verify_safe_py_code(distribution)
|
||||
|
||||
bin_path = os.path.join(venv, 'bin/python')
|
||||
if not os.path.exists(bin_path):
|
||||
raise salt.exceptions.CommandExecutionError("Path does not appear to be a virtualenv: '{0}'".format(venv))
|
||||
_not_a_virtualenv(venv)
|
||||
|
||||
ret = __salt__['cmd.exec_code_all'](bin_path, "import pkg_resources; print(pkg_resources.get_distribution('{0}').location)".format(distribution))
|
||||
ret = __salt__['cmd.exec_code_all'](
|
||||
bin_path,
|
||||
'import pkg_resources; '
|
||||
"print(pkg_resources.get_distribution('{0}').location)".format(
|
||||
distribution
|
||||
)
|
||||
)
|
||||
|
||||
if ret['retcode'] != 0:
|
||||
raise salt.exceptions.CommandExecutionError('{stdout}\n{stderr}'.format(bin_path=bin_path, **ret))
|
||||
raise CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
|
||||
return ret['stdout']
|
||||
|
||||
|
||||
def get_resource_path(venv, package_or_requirement=None, resource_name=None, package=None, resource=None):
|
||||
def get_resource_path(venv,
|
||||
package_or_requirement=None,
|
||||
resource_name=None,
|
||||
package=None,
|
||||
resource=None):
|
||||
'''
|
||||
Returns the path to a resource of a package or a distribution inside a virtualenv
|
||||
Returns the path to a resource of a package or a distribution inside a
|
||||
virtualenv
|
||||
|
||||
venv
|
||||
Path to the virtualenv.
|
||||
Path to the virtualenv
|
||||
|
||||
package
|
||||
Name of the package in which the resource resides
|
||||
|
||||
.. versionadded:: Boron
|
||||
Name of the package where the resource resides in.
|
||||
|
||||
package_or_requirement
|
||||
Deprecated in favor of package.
|
||||
Name of the package in which the resource resides
|
||||
|
||||
.. deprecated:: Boron
|
||||
Use ``package`` instead.
|
||||
|
||||
resource
|
||||
Name of the resource of which the path is to be returned
|
||||
|
||||
.. versionadded:: Boron
|
||||
Name of the resource of which the path is to be returned.
|
||||
|
||||
resource_name
|
||||
Deprecated in favor of resource.
|
||||
Name of the resource of which the path is to be returned
|
||||
|
||||
.. deprecated:: Boron
|
||||
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -357,49 +410,84 @@ def get_resource_path(venv, package_or_requirement=None, resource_name=None, pac
|
||||
salt '*' virtualenv.get_resource_path /path/to/my/venv my_package my/resource.xml
|
||||
'''
|
||||
if package_or_requirement is not None:
|
||||
salt.utils.warn_until('Nitrogen', "Use 'package' in favor of 'package_or_requirement'.")
|
||||
salt.utils.warn_until(
|
||||
'Nitrogen',
|
||||
'The \'package_or_requirement\' argument to '
|
||||
'virtualenv.get_resource_path is deprecated. Please use '
|
||||
'\'package\' instead.'
|
||||
)
|
||||
if package is not None:
|
||||
raise salt.exceptions.CommandExecutionError("Do not use 'package' and 'package_or_requirement' as the same time.")
|
||||
raise CommandExecutionError(
|
||||
'Only one of \'package\' and \'package_or_requirement\' is '
|
||||
'permitted.'
|
||||
)
|
||||
package = package_or_requirement
|
||||
if resource_name is not None:
|
||||
salt.utils.warn_until('Nitrogen', "Use 'resource' in favor of 'resource_name'.")
|
||||
salt.utils.warn_until(
|
||||
'Nitrogen',
|
||||
'The \'resource_name\' argument to virtualenv.get_resource_path '
|
||||
'is deprecated. Please use \'resource\' instead.'
|
||||
)
|
||||
if resource is not None:
|
||||
raise salt.exceptions.CommandExecutionError("Do not use 'resource' and 'resource_name' as the same time.")
|
||||
raise CommandExecutionError(
|
||||
'Only one of \'resource\' and \'resource_name\' is permitted.'
|
||||
)
|
||||
resource = resource_name
|
||||
|
||||
if not salt.utils.verify.safe_py_code(package):
|
||||
raise salt.exceptions.CommandExecutionError
|
||||
if not salt.utils.verify.safe_py_code(resource):
|
||||
raise salt.exceptions.CommandExecutionError
|
||||
_verify_safe_py_code(package, resource)
|
||||
|
||||
bin_path = os.path.join(venv, 'bin/python')
|
||||
if not os.path.exists(bin_path):
|
||||
raise salt.exceptions.CommandExecutionError("Path does not appear to be a virtualenv: '{0}'".format(venv))
|
||||
_not_a_virtualenv(venv)
|
||||
|
||||
ret = __salt__['cmd.exec_code_all'](bin_path, "import pkg_resources; print pkg_resources.resource_filename('{0}', '{1}')".format(package, resource))
|
||||
ret = __salt__['cmd.exec_code_all'](
|
||||
bin_path,
|
||||
'import pkg_resources; '
|
||||
"print(pkg_resources.resource_filename('{0}', '{1}'))".format(
|
||||
package,
|
||||
resource
|
||||
)
|
||||
)
|
||||
|
||||
if ret['retcode'] != 0:
|
||||
raise salt.exceptions.CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
raise CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
|
||||
return ret['stdout']
|
||||
|
||||
|
||||
def get_resource_content(venv, package_or_requirement=None, resource_name=None, package=None, resource=None):
|
||||
def get_resource_content(venv,
|
||||
package_or_requirement=None,
|
||||
resource_name=None,
|
||||
package=None,
|
||||
resource=None):
|
||||
'''
|
||||
Returns the content of a resource of a package or a distribution inside a virtualenv
|
||||
Returns the content of a resource of a package or a distribution inside a
|
||||
virtualenv
|
||||
|
||||
venv
|
||||
Path to the virtualenv.
|
||||
Path to the virtualenv
|
||||
|
||||
package
|
||||
Name of the package in which the resource resides
|
||||
|
||||
.. versionadded:: Boron
|
||||
Name of the package where the resource resides in.
|
||||
|
||||
package_or_requirement
|
||||
Deprecated in favor of package.
|
||||
Name of the package in which the resource resides
|
||||
|
||||
.. deprecated:: Boron
|
||||
Use ``package`` instead.
|
||||
|
||||
resource
|
||||
Name of the resource of which the content is to be returned
|
||||
|
||||
.. versionadded:: Boron
|
||||
Name of the resource of which the content is to be returned.
|
||||
|
||||
resource_name
|
||||
Deprecated in favor of resource.
|
||||
Name of the resource of which the content is to be returned
|
||||
|
||||
.. deprecated:: Boron
|
||||
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -408,29 +496,48 @@ def get_resource_content(venv, package_or_requirement=None, resource_name=None,
|
||||
salt '*' virtualenv.get_resource_content /path/to/my/venv my_package my/resource.xml
|
||||
'''
|
||||
if package_or_requirement is not None:
|
||||
salt.utils.warn_until('Nitrogen', "Use 'package' in favor of 'package_or_requirement'.")
|
||||
salt.utils.warn_until(
|
||||
'Nitrogen',
|
||||
'The \'package_or_requirement\' argument to '
|
||||
'virtualenv.get_resource_content is deprecated. Please use '
|
||||
'\'package\' instead.'
|
||||
)
|
||||
if package is not None:
|
||||
raise salt.exceptions.CommandExecutionError("Do not use 'package' and 'package_or_requirement' as the same time.")
|
||||
raise CommandExecutionError(
|
||||
'Only one of \'package\' and \'package_or_requirement\' is '
|
||||
'permitted.'
|
||||
)
|
||||
package = package_or_requirement
|
||||
if resource_name is not None:
|
||||
salt.utils.warn_until('Nitrogen', "Use 'resource' in favor of 'resource_name'.")
|
||||
salt.utils.warn_until(
|
||||
'Nitrogen',
|
||||
'The \'resource_name\' argument to '
|
||||
'virtualenv.get_resource_content is deprecated. Please use '
|
||||
'\'resource\' instead.'
|
||||
)
|
||||
if resource is not None:
|
||||
raise salt.exceptions.CommandExecutionError("Do not use 'resource' and 'resource_name' as the same time.")
|
||||
raise CommandExecutionError(
|
||||
'Only one of \'resource\' and \'resource_name\' is permitted.'
|
||||
)
|
||||
resource = resource_name
|
||||
|
||||
if not salt.utils.verify.safe_py_code(package):
|
||||
raise salt.exceptions.CommandExecutionError
|
||||
if not salt.utils.verify.safe_py_code(resource):
|
||||
raise salt.exceptions.CommandExecutionError
|
||||
_verify_safe_py_code(package, resource)
|
||||
|
||||
bin_path = os.path.join(venv, 'bin/python')
|
||||
if not os.path.exists(bin_path):
|
||||
raise salt.exceptions.CommandExecutionError("Path does not appear to be a virtualenv: '{0}'".format(venv))
|
||||
_not_a_virtualenv(venv)
|
||||
|
||||
ret = __salt__['cmd.exec_code_all'](bin_path, "import pkg_resources; print pkg_resources.resource_string('{0}', '{1}')".format(package, resource))
|
||||
ret = __salt__['cmd.exec_code_all'](
|
||||
bin_path,
|
||||
'import pkg_resources; '
|
||||
"print(pkg_resources.resource_string('{0}', '{1}'))".format(
|
||||
package,
|
||||
resource
|
||||
)
|
||||
)
|
||||
|
||||
if ret['retcode'] != 0:
|
||||
raise salt.exceptions.CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
raise CommandExecutionError('{stdout}\n{stderr}'.format(**ret))
|
||||
|
||||
return ret['stdout']
|
||||
|
||||
@ -448,7 +555,7 @@ def _install_script(source, cwd, python, user, saltenv='base', use_vt=False):
|
||||
os.chown(tmppath, __salt__['file.user_to_uid'](user), -1)
|
||||
try:
|
||||
return __salt__['cmd.run_all'](
|
||||
'{0} {1}'.format(python, tmppath),
|
||||
[python, tmppath],
|
||||
runas=user,
|
||||
cwd=cwd,
|
||||
env={'VIRTUAL_ENV': cwd},
|
||||
|
@ -1083,7 +1083,11 @@ def symlink(src, link):
|
||||
return True
|
||||
except pywinerror as exc:
|
||||
raise CommandExecutionError(
|
||||
'Could not create {0!r} - [{1}] {2}'.format(link, exc.winerror, exc.strerror)
|
||||
'Could not create \'{0}\' - [{1}] {2}'.format(
|
||||
link,
|
||||
exc.winerror,
|
||||
exc.strerror
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
|
@ -157,7 +157,9 @@ def is_enabled(iface):
|
||||
iface_found = True
|
||||
return line.split()[-1] == 'Connected'
|
||||
if not iface_found:
|
||||
raise CommandExecutionError('Interface {0!r} not found'.format(iface))
|
||||
raise CommandExecutionError(
|
||||
'Interface \'{0}\' not found'.format(iface)
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
@ -219,7 +221,9 @@ def get_subnet_length(mask):
|
||||
salt -G 'os_family:Windows' ip.get_subnet_length 255.255.255.0
|
||||
'''
|
||||
if not salt.utils.validate.net.netmask(mask):
|
||||
raise SaltInvocationError('{0!r} is not a valid netmask'.format(mask))
|
||||
raise SaltInvocationError(
|
||||
'\'{0}\' is not a valid netmask'.format(mask)
|
||||
)
|
||||
return salt.utils.network.get_net_size(mask)
|
||||
|
||||
|
||||
@ -262,11 +266,11 @@ def set_static_ip(iface, addr, gateway=None, append=False):
|
||||
return {}
|
||||
|
||||
if not salt.utils.validate.net.ipv4_addr(addr):
|
||||
raise SaltInvocationError('Invalid address {0!r}'.format(addr))
|
||||
raise SaltInvocationError('Invalid address \'{0}\''.format(addr))
|
||||
|
||||
if gateway and not salt.utils.validate.net.ipv4_addr(addr):
|
||||
raise SaltInvocationError(
|
||||
'Invalid default gateway {0!r}'.format(gateway)
|
||||
'Invalid default gateway \'{0}\''.format(gateway)
|
||||
)
|
||||
|
||||
if '/' not in addr:
|
||||
@ -274,8 +278,8 @@ def set_static_ip(iface, addr, gateway=None, append=False):
|
||||
|
||||
if append and _find_addr(iface, addr):
|
||||
raise CommandExecutionError(
|
||||
'Address {0!r} already exists on interface '
|
||||
'{1!r}'.format(addr, iface)
|
||||
'Address \'{0}\' already exists on interface '
|
||||
'\'{1}\''.format(addr, iface)
|
||||
)
|
||||
|
||||
cmd = ['netsh', 'interface', 'ip']
|
||||
|
@ -809,12 +809,14 @@ def rename(name, new_name):
|
||||
# Load information for the current name
|
||||
current_info = info(name)
|
||||
if not current_info:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
|
||||
# Look for an existing user with the new name
|
||||
new_info = info(new_name)
|
||||
if new_info:
|
||||
raise CommandExecutionError('User {0!r} already exists'.format(new_name))
|
||||
raise CommandExecutionError(
|
||||
'User \'{0}\' already exists'.format(new_name)
|
||||
)
|
||||
|
||||
# Rename the user account
|
||||
# Connect to WMI
|
||||
@ -825,7 +827,7 @@ def rename(name, new_name):
|
||||
try:
|
||||
user = c.Win32_UserAccount(Name=name)[0]
|
||||
except IndexError:
|
||||
raise CommandExecutionError('User {0!r} does not exist'.format(name))
|
||||
raise CommandExecutionError('User \'{0}\' does not exist'.format(name))
|
||||
|
||||
# Rename the user
|
||||
result = user.Rename(new_name)[0]
|
||||
@ -844,16 +846,12 @@ def rename(name, new_name):
|
||||
8: 'Operation is not allowed on specified special groups: user, admin, local, or guest',
|
||||
9: 'Other API error',
|
||||
10: 'Internal error'}
|
||||
raise CommandExecutionError('There was an error renaming {0!r} to {1!r}. Error: {2}'.format(name, new_name, error_dict[result]))
|
||||
raise CommandExecutionError(
|
||||
'There was an error renaming \'{0}\' to \'{1}\'. Error: {2}'
|
||||
.format(name, new_name, error_dict[result])
|
||||
)
|
||||
|
||||
# Load information for the new name
|
||||
post_info = info(new_name)
|
||||
|
||||
# Verify that the name has changed
|
||||
if post_info['name'] != current_info['name']:
|
||||
return post_info['name'] == new_name
|
||||
|
||||
return False
|
||||
return info(new_name).get('name') == new_name
|
||||
|
||||
|
||||
def current(sam=False):
|
||||
|
@ -24,8 +24,6 @@ from distutils.version import LooseVersion as _LooseVersion # pylint: disable=n
|
||||
# Import 3rd-party libs
|
||||
# pylint: disable=import-error,redefined-builtin
|
||||
import salt.ext.six as six
|
||||
from salt.ext.six.moves import shlex_quote as _cmd_quote
|
||||
from salt.ext.six.moves import range # pylint: disable=redefined-builtin
|
||||
|
||||
try:
|
||||
import yum
|
||||
@ -43,6 +41,7 @@ except ImportError:
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.itertools
|
||||
import salt.utils.decorators as decorators
|
||||
import salt.utils.pkg.rpm
|
||||
from salt.exceptions import (
|
||||
@ -80,7 +79,8 @@ def _yum():
|
||||
'''
|
||||
contextkey = 'yum_bin'
|
||||
if contextkey not in __context__:
|
||||
if 'fedora' in __grains__['os'].lower() and int(__grains__['osrelease']) >= 22:
|
||||
if 'fedora' in __grains__['os'].lower() \
|
||||
and int(__grains__['osrelease']) >= 22:
|
||||
__context__[contextkey] = 'dnf'
|
||||
else:
|
||||
__context__[contextkey] = 'yum'
|
||||
@ -110,8 +110,8 @@ def _check_repoquery():
|
||||
if not salt.utils.which('repoquery'):
|
||||
__salt__['cmd.run'](
|
||||
[_yum(), '-y', 'install', 'yum-utils'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False,
|
||||
output_loglevel='trace'
|
||||
)
|
||||
# Check again now that we've installed yum-utils
|
||||
if not salt.utils.which('repoquery'):
|
||||
@ -127,30 +127,33 @@ def _repoquery(repoquery_args,
|
||||
_check_repoquery()
|
||||
|
||||
if _yum() == 'dnf':
|
||||
_query_format = query_format.replace('-%{VERSION}_', '-%{EPOCH}:%{VERSION}_')
|
||||
_query_format = query_format.replace(
|
||||
'-%{VERSION}_',
|
||||
'-%{EPOCH}:%{VERSION}_'
|
||||
)
|
||||
else:
|
||||
_query_format = query_format
|
||||
|
||||
cmd = 'repoquery --plugins --queryformat {0} {1}'.format(
|
||||
_cmd_quote(_query_format), repoquery_args
|
||||
)
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
cmd = ['repoquery', '--plugins', '--queryformat', _query_format]
|
||||
cmd.extend(repoquery_args)
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False)
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
# When checking for packages some yum modules return data via
|
||||
# stderr that don't cause non-zero return codes. j perfect
|
||||
# stderr that don't cause non-zero return codes. A perfect
|
||||
# example of this is when spacewalk is installed but not yet
|
||||
# registered. We should ignore those when getting pkginfo.
|
||||
if 'stderr' in call and not salt.utils.is_true(ignore_stderr):
|
||||
comment += call['stderr']
|
||||
if 'stdout' in call:
|
||||
comment += call['stdout']
|
||||
raise CommandExecutionError(
|
||||
'{0}'.format(comment)
|
||||
)
|
||||
raise CommandExecutionError(comment)
|
||||
else:
|
||||
if _yum() == 'dnf':
|
||||
# Remove the epoch when it is zero to maintain backward compatibility
|
||||
# Remove the epoch when it is zero to maintain backward
|
||||
# compatibility
|
||||
remove_zero_epoch = call['stdout'].replace('-0:', '-')
|
||||
out = remove_zero_epoch
|
||||
else:
|
||||
@ -160,7 +163,7 @@ def _repoquery(repoquery_args,
|
||||
|
||||
def _get_repo_options(**kwargs):
|
||||
'''
|
||||
Returns a string of '--enablerepo' and '--disablerepo' options to be used
|
||||
Returns a list of '--enablerepo' and '--disablerepo' options to be used
|
||||
in the yum command, based on the kwargs.
|
||||
'''
|
||||
# Get repo options from the kwargs
|
||||
@ -173,61 +176,50 @@ def _get_repo_options(**kwargs):
|
||||
if repo and not fromrepo:
|
||||
fromrepo = repo
|
||||
|
||||
repo_arg = ''
|
||||
repo_arg = []
|
||||
if fromrepo:
|
||||
log.info('Restricting to repo \'{0}\''.format(fromrepo))
|
||||
repo_arg = ('--disablerepo=\'{0}\' --enablerepo=\'{1}\''
|
||||
.format('*', fromrepo))
|
||||
repo_arg.extend(['--disablerepo=*', '--enablerepo=' + fromrepo])
|
||||
else:
|
||||
repo_arg = ''
|
||||
if disablerepo:
|
||||
if isinstance(disablerepo, list):
|
||||
for repo_item in disablerepo:
|
||||
log.info('Disabling repo \'{0}\''.format(repo_item))
|
||||
repo_arg += '--disablerepo=\'{0}\' '.format(repo_item)
|
||||
else:
|
||||
log.info('Disabling repo \'{0}\''.format(disablerepo))
|
||||
repo_arg += '--disablerepo=\'{0}\''.format(disablerepo)
|
||||
targets = [disablerepo] \
|
||||
if not isinstance(disablerepo, list) \
|
||||
else disablerepo
|
||||
log.info('Disabling repo(s): {0}'.format(', '.join(disablerepo)))
|
||||
repo_arg.extend(
|
||||
['--disablerepo={0}'.format(x) for x in disablerepo]
|
||||
)
|
||||
if enablerepo:
|
||||
if isinstance(enablerepo, list):
|
||||
for repo_item in enablerepo:
|
||||
log.info('Enabling repo \'{0}\''.format(repo_item))
|
||||
repo_arg += '--enablerepo=\'{0}\' '.format(repo_item)
|
||||
else:
|
||||
log.info('Enabling repo \'{0}\''.format(enablerepo))
|
||||
repo_arg += '--enablerepo=\'{0}\''.format(enablerepo)
|
||||
targets = [enablerepo] \
|
||||
if not isinstance(enablerepo, list) \
|
||||
else enablerepo
|
||||
log.info('Enabling repo(s): {0}'.format(', '.join(enablerepo)))
|
||||
repo_arg.extend(['--enablerepo={0}'.format(x) for x in enablerepo])
|
||||
return repo_arg
|
||||
|
||||
|
||||
def _get_excludes_option(**kwargs):
|
||||
'''
|
||||
Returns a string of '--disableexcludes' option to be used in the yum command,
|
||||
Returns a list of '--disableexcludes' option to be used in the yum command,
|
||||
based on the kwargs.
|
||||
'''
|
||||
disable_excludes_arg = ''
|
||||
disable_excludes = kwargs.get('disableexcludes', '')
|
||||
|
||||
if disable_excludes:
|
||||
log.info('Disabling excludes for \'{0}\''.format(disable_excludes))
|
||||
disable_excludes_arg = \
|
||||
'--disableexcludes=\'{0}\''.format(disable_excludes)
|
||||
|
||||
return disable_excludes_arg
|
||||
return ['--disableexcludes={0}'.format(disable_excludes)]
|
||||
return []
|
||||
|
||||
|
||||
def _get_branch_option(**kwargs):
|
||||
'''
|
||||
Returns a string of '--branch' option to be used in the yum command,
|
||||
Returns a list of '--branch' option to be used in the yum command,
|
||||
based on the kwargs. This feature requires 'branch' plugin for YUM.
|
||||
'''
|
||||
# Get branch option from the kwargs
|
||||
branch = kwargs.get('branch', '')
|
||||
|
||||
branch_arg = ''
|
||||
if branch:
|
||||
log.info('Adding branch \'{0}\''.format(branch))
|
||||
branch_arg = '--branch=\'{0}\''.format(branch)
|
||||
return branch_arg
|
||||
return ['--branch={0}'.format(branch)]
|
||||
return []
|
||||
|
||||
|
||||
def _get_yum_config():
|
||||
@ -425,11 +417,10 @@ def latest_version(*names, **kwargs):
|
||||
|
||||
# Get updates for specified package(s)
|
||||
# Sort by version number (highest to lowest) for loop below
|
||||
repoquery_args = repo_arg + exclude_arg + ['--pkgnarrow=available']
|
||||
repoquery_args.extend(names)
|
||||
updates = sorted(
|
||||
_repoquery_pkginfo(
|
||||
'{0} {1} --pkgnarrow=available {2}'
|
||||
.format(repo_arg, exclude_arg, ' '.join(names))
|
||||
),
|
||||
_repoquery_pkginfo(repoquery_args),
|
||||
key=lambda pkginfo: _LooseVersion(pkginfo.version),
|
||||
reverse=True
|
||||
)
|
||||
@ -628,9 +619,8 @@ def list_repo_pkgs(*args, **kwargs):
|
||||
|
||||
ret = {}
|
||||
for repo in repos:
|
||||
repoquery_cmd = '--all --repoid="{0}" --show-duplicates'.format(repo)
|
||||
for arg in args:
|
||||
repoquery_cmd += ' "{0}"'.format(arg)
|
||||
repoquery_cmd = ['--all', '--repoid={0}'.format(repo),
|
||||
'--show-duplicates'] + list(args)
|
||||
all_pkgs = _repoquery_pkginfo(repoquery_cmd)
|
||||
for pkg in all_pkgs:
|
||||
repo_dict = ret.setdefault(pkg.repoid, {})
|
||||
@ -669,9 +659,10 @@ def list_upgrades(refresh=True, **kwargs):
|
||||
|
||||
if salt.utils.is_true(refresh):
|
||||
refresh_db(**kwargs)
|
||||
updates = _repoquery_pkginfo(
|
||||
'{0} {1} --all --pkgnarrow=updates'.format(repo_arg, exclude_arg)
|
||||
)
|
||||
|
||||
repoquery_args = repo_arg + exclude_arg
|
||||
repoquery_args.extend(['--all', '--pkgnarrow=updates'])
|
||||
updates = _repoquery_pkginfo(repoquery_args)
|
||||
return dict([(x.name, x.version) for x in updates])
|
||||
|
||||
|
||||
@ -728,11 +719,11 @@ def check_db(*names, **kwargs):
|
||||
salt '*' pkg.check_db <package1> <package2> <package3> fromrepo=epel-testing
|
||||
salt '*' pkg.check_db <package1> <package2> <package3> disableexcludes=main
|
||||
'''
|
||||
normalize = kwargs.pop('normalize') if kwargs.get('normalize') else False
|
||||
normalize = kwargs.pop('normalize', True)
|
||||
repo_arg = _get_repo_options(**kwargs)
|
||||
exclude_arg = _get_excludes_option(**kwargs)
|
||||
repoquery_base = \
|
||||
'{0} {1} --all --quiet --whatprovides'.format(repo_arg, exclude_arg)
|
||||
repo_arg + exclude_arg + ['-all', '--quiet', '--whatprovides']
|
||||
|
||||
if 'pkg._avail' in __context__:
|
||||
avail = __context__['pkg._avail']
|
||||
@ -740,7 +731,7 @@ def check_db(*names, **kwargs):
|
||||
# get list of available packages
|
||||
avail = []
|
||||
lines = _repoquery(
|
||||
'{0} --pkgnarrow=all --all'.format(repo_arg),
|
||||
repo_arg + ['--pkgnarrow=all', '--all'],
|
||||
query_format='%{NAME}_|-%{ARCH}'
|
||||
)
|
||||
for line in lines:
|
||||
@ -755,7 +746,7 @@ def check_db(*names, **kwargs):
|
||||
__context__['pkg._avail'] = avail
|
||||
|
||||
ret = {}
|
||||
repoquery_cmd = repoquery_base + ' {0}'.format(" ".join(names))
|
||||
repoquery_cmd = repoquery_base + list(names)
|
||||
provides = sorted(
|
||||
set(x.name for x in _repoquery_pkginfo(repoquery_cmd))
|
||||
)
|
||||
@ -816,22 +807,18 @@ def refresh_db(**kwargs):
|
||||
exclude_arg = _get_excludes_option(**kwargs)
|
||||
branch_arg = _get_branch_option(**kwargs)
|
||||
|
||||
clean_cmd = 'yum -q clean expire-cache {repo} {exclude} {branch}'.format(
|
||||
repo=repo_arg,
|
||||
exclude=exclude_arg,
|
||||
branch=branch_arg
|
||||
)
|
||||
update_cmd = 'yum -q check-update {repo} {exclude} {branch}'.format(
|
||||
repo=repo_arg,
|
||||
exclude=exclude_arg,
|
||||
branch=branch_arg
|
||||
)
|
||||
clean_cmd = ['yum', '-q', 'clean', 'expire-cache']
|
||||
update_cmd = ['yum', '-q', 'check-update']
|
||||
for args in (repo_arg, exclude_arg, branch_arg):
|
||||
if args:
|
||||
clean_cmd.extend(args)
|
||||
update_cmd.extend(args)
|
||||
|
||||
__salt__['cmd.run'](clean_cmd)
|
||||
return retcodes.get(
|
||||
__salt__['cmd.retcode'](update_cmd, ignore_retcode=True),
|
||||
False
|
||||
)
|
||||
__salt__['cmd.run'](clean_cmd, python_shell=False)
|
||||
result = __salt__['cmd.retcode'](update_cmd,
|
||||
ignore_retcode=True,
|
||||
python_shell=False)
|
||||
return retcodes.get(result, False)
|
||||
|
||||
|
||||
def clean_metadata(**kwargs):
|
||||
@ -1056,7 +1043,7 @@ def install(name=None,
|
||||
arch = '.' + archpart
|
||||
pkgname = namepart
|
||||
|
||||
pkgstr = '"{0}-{1}{2}"'.format(pkgname, version_num, arch)
|
||||
pkgstr = '{0}-{1}{2}'.format(pkgname, version_num, arch)
|
||||
else:
|
||||
pkgstr = pkgpath
|
||||
|
||||
@ -1075,44 +1062,40 @@ def install(name=None,
|
||||
else:
|
||||
downgrade.append(pkgstr)
|
||||
|
||||
if targets:
|
||||
if _yum() == 'dnf':
|
||||
dnf_args = '--best --allowerasing'
|
||||
else:
|
||||
dnf_args = ''
|
||||
yum_command = _yum()
|
||||
|
||||
cmd = '{yum_command} -y {dnf} {repo} {exclude} {branch} {gpgcheck} install {pkg}'.format(
|
||||
yum_command=_yum(),
|
||||
dnf=dnf_args,
|
||||
repo=repo_arg,
|
||||
exclude=exclude_arg,
|
||||
branch=branch_arg,
|
||||
gpgcheck='--nogpgcheck' if skip_verify else '',
|
||||
pkg=' '.join(targets),
|
||||
)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
def _add_common_args(cmd):
|
||||
'''
|
||||
DRY function to add args common to all yum/dnf commands
|
||||
'''
|
||||
for args in (repo_arg, exclude_arg, branch_arg):
|
||||
if args:
|
||||
cmd.extend(args)
|
||||
if skip_verify:
|
||||
cmd.append('--nogpgcheck')
|
||||
|
||||
if targets:
|
||||
cmd = [yum_command, '-y']
|
||||
if yum_command == 'dnf':
|
||||
cmd.extend(['--best', '--allowerasing'])
|
||||
_add_common_args(cmd)
|
||||
cmd.append('install')
|
||||
cmd.extend(targets)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
if downgrade:
|
||||
cmd = '{yum_command} -y {repo} {exclude} {branch} {gpgcheck} downgrade {pkg}'.format(
|
||||
yum_command=_yum(),
|
||||
repo=repo_arg,
|
||||
exclude=exclude_arg,
|
||||
branch=branch_arg,
|
||||
gpgcheck='--nogpgcheck' if skip_verify else '',
|
||||
pkg=' '.join(downgrade),
|
||||
)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
cmd = [yum_command, '-y']
|
||||
_add_common_args(cmd)
|
||||
cmd.append('downgrade')
|
||||
cmd.extend(downgrade)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
if to_reinstall:
|
||||
cmd = '{yum_command} -y {repo} {exclude} {branch} {gpgcheck} reinstall {pkg}'.format(
|
||||
yum_command=_yum(),
|
||||
repo=repo_arg,
|
||||
exclude=exclude_arg,
|
||||
branch=branch_arg,
|
||||
gpgcheck='--nogpgcheck' if skip_verify else '',
|
||||
pkg=' '.join(six.itervalues(to_reinstall)),
|
||||
)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
cmd = [yum_command, '-y']
|
||||
_add_common_args(cmd)
|
||||
cmd.append('reinstall')
|
||||
cmd.extend(six.itervalues(to_reinstall))
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
@ -1234,16 +1217,16 @@ def upgrade(refresh=True, skip_verify=False, name=None, pkgs=None, normalize=Tru
|
||||
pkgname, version_num = pkg_item_list
|
||||
targets.append(pkgname)
|
||||
|
||||
cmd = '{yum_command} -q -y {repo} {exclude} {branch} {gpgcheck} upgrade {pkgs}'.format(
|
||||
yum_command=_yum(),
|
||||
repo=repo_arg,
|
||||
exclude=exclude_arg,
|
||||
branch=branch_arg,
|
||||
gpgcheck='--nogpgcheck' if skip_verify else '',
|
||||
pkgs=' '.join(targets)
|
||||
)
|
||||
cmd = [_yum(), '-q', '-y']
|
||||
for args in (repo_arg, exclude_arg, branch_arg):
|
||||
if args:
|
||||
cmd.extend(args)
|
||||
if skip_verify:
|
||||
cmd.append('--nogpgcheck')
|
||||
cmd.append('upgrade')
|
||||
cmd.extend(targets)
|
||||
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
ret = salt.utils.compare_dicts(old, new)
|
||||
@ -1288,11 +1271,11 @@ def remove(name=None, pkgs=None, **kwargs): # pylint: disable=W0613
|
||||
targets = [x for x in pkg_params if x in old]
|
||||
if not targets:
|
||||
return {}
|
||||
quoted_targets = [_cmd_quote(target) for target in targets]
|
||||
cmd = '{yum_command} -q -y remove {0}'.format(
|
||||
' '.join(quoted_targets),
|
||||
yum_command=_yum())
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
__salt__['cmd.run'](
|
||||
[_yum(), '-q', '-y', 'remove'] + targets,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
ret = salt.utils.compare_dicts(old, new)
|
||||
@ -1332,7 +1315,7 @@ def purge(name=None, pkgs=None, **kwargs): # pylint: disable=W0613
|
||||
return remove(name=name, pkgs=pkgs)
|
||||
|
||||
|
||||
def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
def hold(name=None, pkgs=None, sources=None, normalize=True, **kwargs): # pylint: disable=W0613
|
||||
'''
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
@ -1356,7 +1339,6 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
salt '*' pkg.hold <package name>
|
||||
salt '*' pkg.hold pkgs='["foo", "bar"]'
|
||||
'''
|
||||
|
||||
on_redhat_5 = __grains__.get('osmajorrelease', None) == '5'
|
||||
lock_pkg = 'yum-versionlock' if on_redhat_5 else 'yum-plugin-versionlock'
|
||||
if lock_pkg not in list_pkgs():
|
||||
@ -1375,7 +1357,7 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
targets = []
|
||||
if pkgs:
|
||||
for pkg in salt.utils.repack_dictlist(pkgs):
|
||||
ret = check_db(pkg)
|
||||
ret = check_db(pkg, normalize=normalize)
|
||||
if not ret[pkg]['found']:
|
||||
raise SaltInvocationError(
|
||||
'Package {0} not available in repository.'.format(name)
|
||||
@ -1385,7 +1367,7 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
for source in sources:
|
||||
targets.append(next(six.iterkeys(source)))
|
||||
else:
|
||||
ret = check_db(name)
|
||||
ret = check_db(name, normalize=normalize)
|
||||
if not ret[name]['found']:
|
||||
raise SaltInvocationError(
|
||||
'Package {0} not available in repository.'.format(name)
|
||||
@ -1409,10 +1391,10 @@ def hold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W0613
|
||||
ret[target]['comment'] = ('Package {0} is set to be held.'
|
||||
.format(target))
|
||||
else:
|
||||
cmd = '{yum_command} -q versionlock {0}'.format(
|
||||
target,
|
||||
yum_command=_yum())
|
||||
out = __salt__['cmd.run_all'](cmd)
|
||||
out = __salt__['cmd.run_all'](
|
||||
[_yum(), '-q', 'versionlock', target],
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
if out['retcode'] == 0:
|
||||
ret[target].update(result=True)
|
||||
@ -1499,12 +1481,10 @@ def unhold(name=None, pkgs=None, sources=None, **kwargs): # pylint: disable=W06
|
||||
ret[target]['comment'] = ('Package {0} is set to be unheld.'
|
||||
.format(target))
|
||||
else:
|
||||
quoted_targets = [_cmd_quote(item) for item in search_locks]
|
||||
cmd = '{yum_command} -q versionlock delete {0}'.format(
|
||||
' '.join(quoted_targets),
|
||||
yum_command=_yum()
|
||||
out = __salt__['cmd.run_all'](
|
||||
[_yum(), '-q', 'versionlock', 'delete'] + search_locks,
|
||||
python_shell=False
|
||||
)
|
||||
out = __salt__['cmd.run_all'](cmd)
|
||||
|
||||
if out['retcode'] == 0:
|
||||
ret[target].update(result=True)
|
||||
@ -1533,8 +1513,10 @@ def get_locked_packages(pattern=None, full=True):
|
||||
|
||||
salt '*' pkg.get_locked_packages
|
||||
'''
|
||||
cmd = '{yum_command} -q versionlock list'.format(yum_command=_yum())
|
||||
ret = __salt__['cmd.run'](cmd).split('\n')
|
||||
out = __salt__['cmd.run'](
|
||||
[_yum(), '-q', 'versionlock', 'list'],
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
if pattern:
|
||||
if full:
|
||||
@ -1549,7 +1531,7 @@ def get_locked_packages(pattern=None, full=True):
|
||||
pat = re.compile(_pat)
|
||||
|
||||
current_locks = []
|
||||
for item in ret:
|
||||
for item in salt.utils.itertools.split(out, '\n'):
|
||||
match = pat.search(item)
|
||||
if match:
|
||||
if not full:
|
||||
@ -1596,41 +1578,47 @@ def group_list():
|
||||
|
||||
salt '*' pkg.group_list
|
||||
'''
|
||||
ret = {'installed': [], 'available': [], 'installed environments': [], 'available environments': [], 'available languages': {}}
|
||||
cmd = '{yum_command} grouplist'.format(yum_command=_yum())
|
||||
out = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace').splitlines()
|
||||
ret = {'installed': [],
|
||||
'available': [],
|
||||
'installed environments': [],
|
||||
'available environments': [],
|
||||
'available languages': {}}
|
||||
|
||||
section_map = {
|
||||
'installed groups:': 'installed',
|
||||
'available groups:': 'available',
|
||||
'installed environment groups:': 'installed environments',
|
||||
'available environment groups:': 'available environments',
|
||||
'available language groups:': 'available languages',
|
||||
}
|
||||
|
||||
out = __salt__['cmd.run_stdout'](
|
||||
[_yum(), 'grouplist'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
key = None
|
||||
for idx in range(len(out)):
|
||||
if out[idx].lower() == 'installed groups:':
|
||||
key = 'installed'
|
||||
continue
|
||||
elif out[idx].lower() == 'available groups:':
|
||||
key = 'available'
|
||||
continue
|
||||
elif out[idx].lower() == 'installed environment groups:':
|
||||
key = 'installed environments'
|
||||
continue
|
||||
elif out[idx].lower() == 'available environment groups:':
|
||||
key = 'available environments'
|
||||
continue
|
||||
elif out[idx].lower() == 'available language groups:':
|
||||
key = 'available languages'
|
||||
continue
|
||||
elif out[idx].lower() == 'done':
|
||||
for line in salt.utils.itertools.split(out, '\n'):
|
||||
line_lc = line.lower()
|
||||
if line_lc == 'done':
|
||||
break
|
||||
|
||||
section_lookup = section_map.get(line_lc)
|
||||
if section_lookup is not None and section_lookup != key:
|
||||
key = section_lookup
|
||||
continue
|
||||
|
||||
# Ignore any administrative comments (plugin info, repo info, etc.)
|
||||
if key is None:
|
||||
continue
|
||||
|
||||
line = line.strip()
|
||||
if key != 'available languages':
|
||||
ret[key].append(out[idx].strip())
|
||||
else:
|
||||
line = out[idx].strip()
|
||||
try:
|
||||
name, lang = re.match(r'(.+) \[(.+)\]', line).groups()
|
||||
except AttributeError:
|
||||
pass
|
||||
ret[key].append(line)
|
||||
else:
|
||||
match = re.match(r'(.+) \[(.+)\]', line)
|
||||
if match:
|
||||
name, lang = match.groups()
|
||||
ret[key][line] = {'name': name, 'language': lang}
|
||||
return ret
|
||||
|
||||
@ -1655,20 +1643,26 @@ def group_info(name):
|
||||
'default packages': [],
|
||||
'description': ''
|
||||
}
|
||||
cmd_template = 'repoquery --plugins --group --grouppkgs={0} --list {1}'
|
||||
cmd_prefix = ['repoquery', '--plugins', '--group', '--list']
|
||||
|
||||
cmd = cmd_template.format('all', _cmd_quote(name))
|
||||
out = __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')
|
||||
cmd = cmd_prefix + ['--grouppkgs=all', name]
|
||||
out = __salt__['cmd.run_stdout'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
all_pkgs = set(out.splitlines())
|
||||
|
||||
if not all_pkgs:
|
||||
raise CommandExecutionError('Group \'{0}\' not found'.format(name))
|
||||
|
||||
for pkgtype in ('mandatory', 'optional', 'default'):
|
||||
cmd = cmd_template.format(pkgtype, _cmd_quote(name))
|
||||
cmd = cmd_prefix + ['--grouppkgs={0}'.format(pkgtype), name]
|
||||
packages = set(
|
||||
__salt__['cmd.run_stdout'](
|
||||
cmd, output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
).splitlines()
|
||||
)
|
||||
ret['{0} packages'.format(pkgtype)].extend(sorted(packages))
|
||||
@ -1679,9 +1673,10 @@ def group_info(name):
|
||||
# considered to be conditional packages.
|
||||
ret['conditional packages'] = sorted(all_pkgs)
|
||||
|
||||
cmd = 'repoquery --plugins --group --info {0}'.format(_cmd_quote(name))
|
||||
out = __salt__['cmd.run_stdout'](
|
||||
cmd, output_loglevel='trace'
|
||||
['repoquery', '--plugins', '--group', '--info', name],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
if out:
|
||||
ret['description'] = '\n'.join(out.splitlines()[1:]).strip()
|
||||
@ -2186,14 +2181,12 @@ def owner(*paths):
|
||||
if not paths:
|
||||
return ''
|
||||
ret = {}
|
||||
cmd_prefix = ['rpm', '-qf', '--queryformat', '%{name}']
|
||||
for path in paths:
|
||||
cmd = 'rpm -qf --queryformat {0} \'{1}\''.format(
|
||||
_cmd_quote('%{{NAME}}'),
|
||||
path
|
||||
)
|
||||
ret[path] = __salt__['cmd.run_stdout'](
|
||||
cmd.format(path),
|
||||
output_loglevel='trace'
|
||||
cmd_prefix + [path],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
if 'not owned' in ret[path].lower():
|
||||
ret[path] = ''
|
||||
@ -2292,11 +2285,12 @@ def download(*packages):
|
||||
except OSError as exc:
|
||||
log.error('Unable to remove {0}: {1}'.format(purge_target, exc))
|
||||
|
||||
cmd = ['yumdownloader', '-q', '--destdir={0}'.format(CACHE_DIR)]
|
||||
cmd.extend(packages)
|
||||
__salt__['cmd.run'](
|
||||
'yumdownloader -q {0} --destdir={1}'.format(
|
||||
' '.join(packages), CACHE_DIR
|
||||
),
|
||||
output_loglevel='trace'
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
ret = {}
|
||||
for dld_result in os.listdir(CACHE_DIR):
|
||||
|
@ -15,6 +15,7 @@ import os
|
||||
# Import 3rd-party libs
|
||||
# pylint: disable=import-error,redefined-builtin,no-name-in-module
|
||||
import salt.ext.six as six
|
||||
from salt.exceptions import SaltInvocationError
|
||||
from salt.ext.six.moves import configparser
|
||||
from salt.ext.six.moves.urllib.parse import urlparse as _urlparse
|
||||
# pylint: enable=import-error,redefined-builtin,no-name-in-module
|
||||
@ -63,7 +64,9 @@ def list_upgrades(refresh=True):
|
||||
refresh_db()
|
||||
ret = {}
|
||||
call = __salt__['cmd.run_all'](
|
||||
'zypper list-updates', output_loglevel='trace'
|
||||
['zypper', 'list-updates'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
@ -149,18 +152,28 @@ def info_available(*names, **kwargs):
|
||||
|
||||
# Run in batches
|
||||
while batch:
|
||||
cmd = 'zypper info -t package {0}'.format(' '.join(batch[:batch_size]))
|
||||
pkg_info.extend(re.split(r"----*", __salt__['cmd.run_stdout'](cmd, output_loglevel='trace')))
|
||||
cmd = ['zypper', 'info', '-t', 'package']
|
||||
cmd.extend(batch[:batch_size])
|
||||
pkg_info.extend(
|
||||
re.split(
|
||||
'----*',
|
||||
__salt__['cmd.run_stdout'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
)
|
||||
)
|
||||
batch = batch[batch_size:]
|
||||
|
||||
for pkg_data in pkg_info:
|
||||
nfo = {}
|
||||
for line in [data for data in pkg_data.split("\n") if ":" in data]:
|
||||
kw = [data.strip() for data in line.split(":", 1)]
|
||||
for line in [data for data in pkg_data.split('\n') if ':' in data]:
|
||||
kw = [data.strip() for data in line.split(':', 1)]
|
||||
if len(kw) == 2 and kw[1]:
|
||||
nfo[kw[0].lower()] = kw[1]
|
||||
if nfo.get("name"):
|
||||
name = nfo.pop("name")
|
||||
if nfo.get('name'):
|
||||
name = nfo.pop('name')
|
||||
ret[name] = nfo
|
||||
|
||||
return ret
|
||||
@ -372,8 +385,15 @@ def del_repo(repo):
|
||||
repos_cfg = _get_configured_repos()
|
||||
for alias in repos_cfg.sections():
|
||||
if alias == repo:
|
||||
cmd = ('zypper -x --non-interactive rr --loose-auth --loose-query {0}'.format(alias))
|
||||
doc = dom.parseString(__salt__['cmd.run'](cmd, output_loglevel='trace'))
|
||||
cmd = ['zypper', '-x', '--non-interactive', 'rr', '--loose-auth',
|
||||
'--loose-query', alias]
|
||||
doc = dom.parseString(
|
||||
__salt__['cmd.run'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
)
|
||||
msg = doc.getElementsByTagName('message')
|
||||
if doc.getElementsByTagName('progress') and msg:
|
||||
return {
|
||||
@ -431,11 +451,13 @@ def mod_repo(repo, **kwargs):
|
||||
url = kwargs.get('url', kwargs.get('mirrorlist', kwargs.get('baseurl')))
|
||||
if not url:
|
||||
raise CommandExecutionError(
|
||||
'Repository \'{0}\' not found and no URL passed to create one.'.format(repo))
|
||||
'Repository \'{0}\' not found and no URL passed'.format(repo)
|
||||
)
|
||||
|
||||
if not _urlparse(url).scheme:
|
||||
raise CommandExecutionError(
|
||||
'Repository \'{0}\' not found and passed URL looks wrong.'.format(repo))
|
||||
'Repository \'{0}\' not found and URL is invalid'.format(repo)
|
||||
)
|
||||
|
||||
# Is there already such repo under different alias?
|
||||
for alias in repos_cfg.sections():
|
||||
@ -454,17 +476,26 @@ def mod_repo(repo, **kwargs):
|
||||
|
||||
if new_url == base_url:
|
||||
raise CommandExecutionError(
|
||||
'Repository \'{0}\' already exists as \'{1}\'.'.format(repo, alias))
|
||||
'Repository \'{0}\' already exists as \'{1}\'.'.format(
|
||||
repo,
|
||||
alias
|
||||
)
|
||||
)
|
||||
|
||||
# Add new repo
|
||||
doc = None
|
||||
try:
|
||||
# Try to parse the output and find the error,
|
||||
# but this not always working (depends on Zypper version)
|
||||
doc = dom.parseString(__salt__['cmd.run'](('zypper -x ar {0} \'{1}\''.format(url, repo)),
|
||||
output_loglevel='trace'))
|
||||
doc = dom.parseString(
|
||||
__salt__['cmd.run'](
|
||||
['zypper', '-x', 'ar', url, repo],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
# No XML out available, but it is still unknown the state of the result.
|
||||
# No XML out available, but the the result is still unknown
|
||||
pass
|
||||
|
||||
if doc:
|
||||
@ -472,14 +503,17 @@ def mod_repo(repo, **kwargs):
|
||||
if msg_nodes:
|
||||
msg_node = msg_nodes[0]
|
||||
if msg_node.getAttribute('type') == 'error':
|
||||
raise CommandExecutionError(msg_node.childNodes[0].nodeValue)
|
||||
raise CommandExecutionError(
|
||||
msg_node.childNodes[0].nodeValue
|
||||
)
|
||||
|
||||
# Verify the repository has been added
|
||||
repos_cfg = _get_configured_repos()
|
||||
if repo not in repos_cfg.sections():
|
||||
raise CommandExecutionError(
|
||||
'Failed add new repository \'{0}\' for unknown reason. '
|
||||
'Please look into Zypper logs.'.format(repo))
|
||||
'Please look into Zypper logs.'.format(repo)
|
||||
)
|
||||
added = True
|
||||
|
||||
# Modify added or existing repo according to the options
|
||||
@ -492,7 +526,9 @@ def mod_repo(repo, **kwargs):
|
||||
cmd_opt.append(kwargs['refresh'] and '--refresh' or '--no-refresh')
|
||||
|
||||
if 'cache' in kwargs:
|
||||
cmd_opt.append(kwargs['cache'] and '--keep-packages' or '--no-keep-packages')
|
||||
cmd_opt.append(
|
||||
kwargs['cache'] and '--keep-packages' or '--no-keep-packages'
|
||||
)
|
||||
|
||||
if 'gpgcheck' in kwargs:
|
||||
cmd_opt.append(kwargs['gpgcheck'] and '--gpgcheck' or '--no-gpgcheck')
|
||||
@ -501,13 +537,17 @@ def mod_repo(repo, **kwargs):
|
||||
cmd_opt.append('--gpg-auto-import-keys')
|
||||
|
||||
if cmd_opt:
|
||||
__salt__['cmd.run'](('zypper -x mr {0} \'{1}\''.format(' '.join(cmd_opt), repo)),
|
||||
output_loglevel='trace')
|
||||
cmd = ['zypper', '-x', 'mr']
|
||||
cmd.extend(cmd_opt)
|
||||
cmd.append(repo)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
# If repo nor added neither modified, error should be thrown
|
||||
if not added and not cmd_opt:
|
||||
raise CommandExecutionError(
|
||||
'Modification of the repository \'{0}\' was not specified.'.format(repo))
|
||||
'Modification of the repository \'{0}\' was not specified.'
|
||||
.format(repo)
|
||||
)
|
||||
|
||||
return get_repo(repo)
|
||||
|
||||
@ -524,17 +564,19 @@ def refresh_db():
|
||||
|
||||
salt '*' pkg.refresh_db
|
||||
'''
|
||||
cmd = 'zypper refresh'
|
||||
cmd = ['zypper', 'refresh']
|
||||
ret = {}
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
if call['retcode'] != 0:
|
||||
comment = ''
|
||||
if 'stderr' in call:
|
||||
comment += call['stderr']
|
||||
|
||||
raise CommandExecutionError(
|
||||
'{0}'.format(comment)
|
||||
call = __salt__['cmd.run_all'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
if call['retcode'] != 0:
|
||||
msg = 'Failed to refresh zypper'
|
||||
if call['stderr']:
|
||||
msg += ': ' + call['stderr']
|
||||
|
||||
raise CommandExecutionError(msg)
|
||||
else:
|
||||
out = call['stdout']
|
||||
|
||||
@ -566,10 +608,10 @@ def install(name=None,
|
||||
|
||||
name
|
||||
The name of the package to be installed. Note that this parameter is
|
||||
ignored if either "pkgs" or "sources" is passed. Additionally, please
|
||||
note that this option can only be used to install packages from a
|
||||
software repository. To install a package file manually, use the
|
||||
"sources" option.
|
||||
ignored if either ``pkgs`` or ``sources`` is passed. Additionally,
|
||||
please note that this option can only be used to install packages from
|
||||
a software repository. To install a package file manually, use the
|
||||
``sources`` option.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -592,7 +634,7 @@ def install(name=None,
|
||||
version
|
||||
Can be either a version number, or the combination of a comparison
|
||||
operator (<, >, <=, >=, =) and a version number (ex. '>1.2.3-4').
|
||||
This parameter is ignored if "pkgs" or "sources" is passed.
|
||||
This parameter is ignored if ``pkgs`` or ``sources`` is passed.
|
||||
|
||||
|
||||
Multiple Package Installation Options:
|
||||
@ -665,8 +707,8 @@ def install(name=None,
|
||||
targets.append('{0}{1}{2}'.format(param, prefix, verstr))
|
||||
log.debug(targets)
|
||||
else:
|
||||
msg = ('Invalid version string {0!r} for package '
|
||||
'{1!r}'.format(version_num, name))
|
||||
msg = ('Invalid version string \'{0}\' for package '
|
||||
'\'{1}\''.format(version_num, name))
|
||||
problems.append(msg)
|
||||
if problems:
|
||||
for problem in problems:
|
||||
@ -679,7 +721,7 @@ def install(name=None,
|
||||
downgrades = []
|
||||
if fromrepo:
|
||||
fromrepoopt = ['--force', '--force-resolution', '--from', fromrepo]
|
||||
log.info('Targeting repo {0!r}'.format(fromrepo))
|
||||
log.info('Targeting repo \'{0}\''.format(fromrepo))
|
||||
else:
|
||||
fromrepoopt = ''
|
||||
cmd_install = ['zypper', '--non-interactive']
|
||||
@ -687,7 +729,7 @@ def install(name=None,
|
||||
cmd_install.append('--no-refresh')
|
||||
if skip_verify:
|
||||
cmd_install.append('--no-gpg-checks')
|
||||
cmd_install += ['install', '--name', '--auto-agree-with-licenses']
|
||||
cmd_install.extend(['install', '--name', '--auto-agree-with-licenses'])
|
||||
if downloadonly:
|
||||
cmd_install.append('--download-only')
|
||||
if fromrepo:
|
||||
@ -714,8 +756,8 @@ def install(name=None,
|
||||
while downgrades:
|
||||
cmd = cmd_install + ['--force'] + downgrades[:500]
|
||||
downgrades = downgrades[500:]
|
||||
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
@ -751,16 +793,20 @@ def upgrade(refresh=True, skip_verify=False):
|
||||
if salt.utils.is_true(refresh):
|
||||
refresh_db()
|
||||
old = list_pkgs()
|
||||
cmd = 'zypper --non-interactive'
|
||||
cmd = ['zypper', '--non-interactive']
|
||||
if skip_verify:
|
||||
cmd += ' --no-gpg-checks'
|
||||
cmd += ' update --auto-agree-with-licenses'
|
||||
call = __salt__['cmd.run_all'](cmd, output_loglevel='trace')
|
||||
cmd.append('--no-gpg-checks')
|
||||
cmd.extend(['update', '--auto-agree-with-licenses'])
|
||||
call = __salt__['cmd.run_all'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
if call['retcode'] != 0:
|
||||
ret['result'] = False
|
||||
if 'stderr' in call:
|
||||
if call['stderr']:
|
||||
ret['comment'] += call['stderr']
|
||||
if 'stdout' in call:
|
||||
if call['stdout']:
|
||||
ret['comment'] += call['stdout']
|
||||
else:
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
@ -779,17 +825,16 @@ def _uninstall(action='remove', name=None, pkgs=None):
|
||||
except MinionError as exc:
|
||||
raise CommandExecutionError(exc)
|
||||
|
||||
purge_arg = '-u' if action == 'purge' else ''
|
||||
old = list_pkgs()
|
||||
targets = [x for x in pkg_params if x in old]
|
||||
if not targets:
|
||||
return {}
|
||||
while targets:
|
||||
cmd = (
|
||||
'zypper --non-interactive remove {0} {1}'
|
||||
.format(purge_arg, ' '.join(targets[:500]))
|
||||
)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
cmd = ['zypper', '--non-interactive', 'remove']
|
||||
if action == 'purge':
|
||||
cmd.append('-u')
|
||||
cmd.extend(targets[:500])
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
targets = targets[500:]
|
||||
__context__.pop('pkg.list_pkgs', None)
|
||||
new = list_pkgs()
|
||||
@ -889,7 +934,8 @@ def list_locks():
|
||||
|
||||
def clean_locks():
|
||||
'''
|
||||
Remove unused locks that do not currently (with regard to repositories used) lock any package.
|
||||
Remove unused locks that do not currently (with regard to repositories
|
||||
used) lock any package.
|
||||
|
||||
CLI Example:
|
||||
|
||||
@ -900,8 +946,8 @@ def clean_locks():
|
||||
if not os.path.exists(LOCKS):
|
||||
return False
|
||||
|
||||
cmd = ('zypper --non-interactive cl')
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace')
|
||||
cmd = ['zypper', '--non-interactive', 'cl']
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
return True
|
||||
|
||||
@ -922,7 +968,9 @@ def remove_lock(name=None, pkgs=None, **kwargs): # pylint: disable=unused-argum
|
||||
locks = list_locks()
|
||||
packages = []
|
||||
try:
|
||||
packages = list(__salt__['pkg_resource.parse_targets'](name, pkgs)[0].keys())
|
||||
packages = list(
|
||||
__salt__['pkg_resource.parse_targets'](name, pkgs)[0].keys()
|
||||
)
|
||||
except MinionError as exc:
|
||||
raise CommandExecutionError(exc)
|
||||
|
||||
@ -935,8 +983,9 @@ def remove_lock(name=None, pkgs=None, **kwargs): # pylint: disable=unused-argum
|
||||
missing.append(pkg)
|
||||
|
||||
if removed:
|
||||
__salt__['cmd.run'](('zypper --non-interactive rl {0}'.format(' '.join(removed))),
|
||||
output_loglevel='trace')
|
||||
cmd = ['zypper', '--non-interactive', 'rl']
|
||||
cmd.extend(removed)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
return {'removed': len(removed), 'not_found': missing}
|
||||
|
||||
@ -957,7 +1006,9 @@ def add_lock(name=None, pkgs=None, **kwargs): # pylint: disable=unused-argument
|
||||
packages = []
|
||||
added = []
|
||||
try:
|
||||
packages = list(__salt__['pkg_resource.parse_targets'](name, pkgs)[0].keys())
|
||||
packages = list(
|
||||
__salt__['pkg_resource.parse_targets'](name, pkgs)[0].keys()
|
||||
)
|
||||
except MinionError as exc:
|
||||
raise CommandExecutionError(exc)
|
||||
|
||||
@ -966,8 +1017,9 @@ def add_lock(name=None, pkgs=None, **kwargs): # pylint: disable=unused-argument
|
||||
added.append(pkg)
|
||||
|
||||
if added:
|
||||
__salt__['cmd.run'](('zypper --non-interactive al {0}'.format(' '.join(added))),
|
||||
output_loglevel='trace')
|
||||
cmd = ['zypper', '--non-interactive', 'al']
|
||||
cmd.extend(added)
|
||||
__salt__['cmd.run'](cmd, output_loglevel='trace', python_shell=False)
|
||||
|
||||
return {'added': len(added), 'packages': added}
|
||||
|
||||
@ -1099,8 +1151,13 @@ def _get_patterns(installed_only=None):
|
||||
List all known patterns in repos.
|
||||
'''
|
||||
patterns = {}
|
||||
doc = dom.parseString(__salt__['cmd.run'](('zypper --xmlout se -t pattern'),
|
||||
output_loglevel='trace'))
|
||||
doc = dom.parseString(
|
||||
__salt__['cmd.run'](
|
||||
['zypper', '--xmlout', 'se', '-t', 'pattern'],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
)
|
||||
for element in doc.getElementsByTagName('solvable'):
|
||||
installed = element.getAttribute('status') == 'installed'
|
||||
if (installed_only and installed) or not installed_only:
|
||||
@ -1148,11 +1205,18 @@ def search(criteria):
|
||||
|
||||
salt '*' pkg.search <criteria>
|
||||
'''
|
||||
doc = dom.parseString(__salt__['cmd.run'](('zypper --xmlout se {0}'.format(criteria)),
|
||||
output_loglevel='trace'))
|
||||
doc = dom.parseString(
|
||||
__salt__['cmd.run'](
|
||||
['zypper', '--xmlout', 'se', criteria],
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
)
|
||||
solvables = doc.getElementsByTagName('solvable')
|
||||
if not solvables:
|
||||
raise CommandExecutionError('No packages found by criteria "{0}".'.format(criteria))
|
||||
raise CommandExecutionError(
|
||||
'No packages found matching \'{0}\''.format(criteria)
|
||||
)
|
||||
|
||||
out = {}
|
||||
for solvable in [s for s in solvables
|
||||
@ -1206,7 +1270,9 @@ def list_products():
|
||||
'''
|
||||
products_dir = '/etc/products.d'
|
||||
if not os.path.exists(products_dir):
|
||||
raise CommandExecutionError('Directory {0} does not exists.'.format(products_dir))
|
||||
raise CommandExecutionError(
|
||||
'Directory {0} does not exist'.format(products_dir)
|
||||
)
|
||||
|
||||
p_data = {}
|
||||
for fname in os.listdir(products_dir):
|
||||
@ -1229,7 +1295,7 @@ def list_products():
|
||||
|
||||
|
||||
def download(*packages):
|
||||
"""
|
||||
'''
|
||||
Download packages to the local disk.
|
||||
|
||||
CLI example:
|
||||
@ -1238,27 +1304,41 @@ def download(*packages):
|
||||
|
||||
salt '*' pkg.download httpd
|
||||
salt '*' pkg.download httpd postfix
|
||||
"""
|
||||
'''
|
||||
if not packages:
|
||||
raise CommandExecutionError("No packages has been specified.")
|
||||
raise SaltInvocationError('No packages specified')
|
||||
|
||||
doc = dom.parseString(__salt__['cmd.run'](
|
||||
('zypper -x --non-interactive download {0}'.format(' '.join(packages))),
|
||||
output_loglevel='trace'))
|
||||
cmd = ['zypper', '-x', '--non-interactive', 'download']
|
||||
cmd.extend(packages)
|
||||
|
||||
doc = dom.parseString(
|
||||
__salt__['cmd.run'](
|
||||
cmd,
|
||||
output_loglevel='trace',
|
||||
python_shell=False
|
||||
)
|
||||
)
|
||||
pkg_ret = {}
|
||||
for dld_result in doc.getElementsByTagName("download-result"):
|
||||
repo = dld_result.getElementsByTagName("repository")[0]
|
||||
for dld_result in doc.getElementsByTagName('download-result'):
|
||||
repo = dld_result.getElementsByTagName('repository')[0]
|
||||
path = dld_result.getElementsByTagName(
|
||||
'localfile')[0].getAttribute('path')
|
||||
pkg_info = {
|
||||
'repository-name': repo.getAttribute("name"),
|
||||
'repository-alias': repo.getAttribute("alias"),
|
||||
'path': dld_result.getElementsByTagName("localfile")[0].getAttribute("path"),
|
||||
'repository-name': repo.getAttribute('name'),
|
||||
'repository-alias': repo.getAttribute('alias'),
|
||||
'path': path
|
||||
}
|
||||
pkg_ret[_get_first_aggregate_text(dld_result.getElementsByTagName("name"))] = pkg_info
|
||||
key = _get_first_aggregate_text(
|
||||
dld_result.getElementsByTagName('name')
|
||||
)
|
||||
pkg_ret[key] = pkg_info
|
||||
|
||||
if pkg_ret:
|
||||
return pkg_ret
|
||||
|
||||
raise CommandExecutionError("Unable to download packages: {0}.".format(', '.join(packages)))
|
||||
raise CommandExecutionError(
|
||||
'Unable to download packages: {0}'.format(', '.join(packages))
|
||||
)
|
||||
|
||||
|
||||
def diff(*paths):
|
||||
@ -1292,6 +1372,9 @@ def diff(*paths):
|
||||
local_pkgs = __salt__['pkg.download'](*pkg_to_paths.keys())
|
||||
for pkg, files in pkg_to_paths.items():
|
||||
for path in files:
|
||||
ret[path] = __salt__['lowpkg.diff'](local_pkgs[pkg]['path'], path) or 'Unchanged'
|
||||
ret[path] = __salt__['lowpkg.diff'](
|
||||
local_pkgs[pkg]['path'],
|
||||
path
|
||||
) or 'Unchanged'
|
||||
|
||||
return ret
|
||||
|
@ -193,7 +193,8 @@ class AtTestCase(TestCase):
|
||||
self.assertEqual(at.atc(101), '\'at.atc\' is not available.')
|
||||
|
||||
with patch.object(at, '_cmd', return_value=''):
|
||||
self.assertDictEqual(at.atc(101), {'error': 'invalid job id 101'})
|
||||
self.assertDictEqual(at.atc(101),
|
||||
{'error': 'invalid job id \'101\''})
|
||||
|
||||
with patch.object(at, '_cmd',
|
||||
return_value='101\tThu Dec 11 19:48:47 2014 A B'):
|
||||
|
@ -26,7 +26,10 @@ class DarwingPkgutilTestCase(TestCase):
|
||||
output = darwin_pkgutil.list_()
|
||||
|
||||
# Then
|
||||
mock_cmd.assert_called_with("/usr/sbin/pkgutil --pkgs")
|
||||
mock_cmd.assert_called_with(
|
||||
['/usr/sbin/pkgutil', '--pkgs'],
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_list_installed_output(self):
|
||||
# Given
|
||||
|
@ -18,14 +18,18 @@ gem.__salt__ = {}
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class TestGemModule(TestCase):
|
||||
|
||||
def test__gem(self):
|
||||
def test_gem(self):
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
with patch.dict(gem.__salt__,
|
||||
{'rvm.is_installed': MagicMock(return_value=False),
|
||||
'rbenv.is_installed': MagicMock(return_value=False),
|
||||
'cmd.run_all': mock}):
|
||||
gem._gem('install rails')
|
||||
mock.assert_called_once_with('gem install rails', runas=None, python_shell=True)
|
||||
gem._gem(['install', 'rails'])
|
||||
mock.assert_called_once_with(
|
||||
['gem', 'install', 'rails'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
rvm_mock = MagicMock()
|
||||
@ -33,18 +37,28 @@ class TestGemModule(TestCase):
|
||||
{'rvm.is_installed': rvm_mock,
|
||||
'rbenv.is_installed': rvm_mock,
|
||||
'cmd.run_all': mock}):
|
||||
gem._gem('install rails', gem_bin="/usr/local/bin/gem")
|
||||
self.assertEqual(False, rvm_mock.called, "Should never call rvm.is_installed if gem_bin provided")
|
||||
mock.assert_called_once_with('/usr/local/bin/gem install rails', runas=None, python_shell=True)
|
||||
gem._gem(['install', 'rails'], gem_bin='/usr/local/bin/gem')
|
||||
self.assertEqual(
|
||||
False,
|
||||
rvm_mock.called,
|
||||
'Should never call rvm.is_installed if gem_bin provided'
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
['/usr/local/bin/gem', 'install', 'rails'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
mock = MagicMock(return_value=None)
|
||||
with patch.dict(gem.__salt__,
|
||||
{'rvm.is_installed': MagicMock(return_value=True),
|
||||
'rbenv.is_installed': MagicMock(return_value=False),
|
||||
'rvm.do': mock}):
|
||||
gem._gem('install rails', ruby='1.9.3')
|
||||
gem._gem(['install', 'rails'], ruby='1.9.3')
|
||||
mock.assert_called_once_with(
|
||||
'1.9.3', 'gem install rails', runas=None
|
||||
'1.9.3',
|
||||
['gem', 'install', 'rails'],
|
||||
runas=None
|
||||
)
|
||||
|
||||
mock = MagicMock(return_value=None)
|
||||
@ -52,9 +66,10 @@ class TestGemModule(TestCase):
|
||||
{'rvm.is_installed': MagicMock(return_value=False),
|
||||
'rbenv.is_installed': MagicMock(return_value=True),
|
||||
'rbenv.do': mock}):
|
||||
gem._gem('install rails')
|
||||
gem._gem(['install', 'rails'])
|
||||
mock.assert_called_once_with(
|
||||
'gem install rails', runas=None
|
||||
['gem', 'install', 'rails'],
|
||||
runas=None
|
||||
)
|
||||
|
||||
def test_install_pre(self):
|
||||
@ -65,7 +80,9 @@ class TestGemModule(TestCase):
|
||||
'cmd.run_all': mock}):
|
||||
gem.install('rails', pre_releases=True)
|
||||
mock.assert_called_once_with(
|
||||
'gem install rails --no-rdoc --no-ri --pre', runas=None, python_shell=True
|
||||
['gem', 'install', 'rails', '--no-rdoc', '--no-ri', '--pre'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_list(self):
|
||||
|
@ -64,7 +64,8 @@ class MacUserTestCase(TestCase):
|
||||
with patch.dict(mac_user.__grains__,
|
||||
{'kernel': 'Darwin', 'osrelease': '10.9.1',
|
||||
'osrelease_info': (10, 9, 1)}):
|
||||
self.assertEqual(mac_user._dscl('username'), {'pid': 4948,
|
||||
self.assertEqual(mac_user._dscl(['username', 'UniqueID', 501]),
|
||||
{'pid': 4948,
|
||||
'retcode': 0,
|
||||
'stderr': '',
|
||||
'stdout': ''})
|
||||
|
@ -70,14 +70,16 @@ class PostgresTestCase(TestCase):
|
||||
owner='otheruser',
|
||||
runas='foo')
|
||||
postgres._run_psql.assert_has_calls([
|
||||
call('/usr/bin/pgsql --no-align --no-readline --no-password --username testuser '
|
||||
'--host testhost --port testport --dbname maint_db '
|
||||
'-c \'ALTER DATABASE "dbname" OWNER TO "otheruser"\'',
|
||||
call(['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'ALTER DATABASE "dbname" OWNER TO "otheruser"'],
|
||||
host='testhost', user='testuser',
|
||||
password='foo', runas='foo', port='testport'),
|
||||
call('/usr/bin/pgsql --no-align --no-readline --no-password --username testuser '
|
||||
'--host testhost --port testport --dbname maint_db '
|
||||
'-c \'ALTER DATABASE "dbname" SET TABLESPACE "testspace"\'',
|
||||
call(['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'ALTER DATABASE "dbname" SET TABLESPACE "testspace"'],
|
||||
host='testhost', user='testuser',
|
||||
password='foo', runas='foo', port='testport')
|
||||
])
|
||||
@ -118,12 +120,12 @@ class PostgresTestCase(TestCase):
|
||||
runas='foo'
|
||||
)
|
||||
|
||||
qstr = (
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password '
|
||||
'--username testuser --host testhost --port testport --dbname maint_db '
|
||||
'-c \'CREATE DATABASE "dbname" WITH TABLESPACE = testspace OWNER = "otheruser"\'')
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
qstr,
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'CREATE DATABASE "dbname" WITH TABLESPACE = testspace '
|
||||
'OWNER = "otheruser"'],
|
||||
host='testhost', user='testuser',
|
||||
password='foo', runas='foo', port='testport')
|
||||
|
||||
@ -187,9 +189,10 @@ class PostgresTestCase(TestCase):
|
||||
runas='foo'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
"/usr/bin/pgsql --no-align --no-readline --no-password --username testuser "
|
||||
"--host testhost --port testport --dbname maint_db "
|
||||
"-c 'DROP DATABASE test_db'",
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'DROP DATABASE test_db'],
|
||||
host='testhost', user='testuser',
|
||||
password='foo', runas='foo', port='testport')
|
||||
|
||||
@ -213,11 +216,13 @@ class PostgresTestCase(TestCase):
|
||||
groups='testgroup',
|
||||
runas='foo'
|
||||
)
|
||||
self.assertTrue(re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password --username testuser '
|
||||
'--host testhost --port testport '
|
||||
'--dbname maint_db -c (\'|\")CREATE ROLE',
|
||||
postgres._run_psql.call_args[0][0]))
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
postgres._run_psql.call_args[0][0][13].startswith('CREATE ROLE')
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0}))
|
||||
@ -233,9 +238,10 @@ class PostgresTestCase(TestCase):
|
||||
runas='foo'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
"/usr/bin/pgsql --no-align --no-readline --no-password --username testuser "
|
||||
"--host testhost --port testport "
|
||||
"--dbname maint_db -c 'DROP ROLE testgroup'",
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'DROP ROLE testgroup'],
|
||||
host='testhost', user='testuser',
|
||||
password='foo', runas='foo', port='testport')
|
||||
|
||||
@ -259,10 +265,16 @@ class PostgresTestCase(TestCase):
|
||||
groups='testgroup',
|
||||
runas='foo'
|
||||
)
|
||||
self.assertTrue(re.match(
|
||||
'.*'
|
||||
'(\'|\")ALTER.* (\\\\)?"testgroup(\\\\)?" .* UNENCRYPTED PASSWORD',
|
||||
postgres._run_psql.call_args[0][0]))
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
re.match(
|
||||
'ALTER.* "testgroup" .* UNENCRYPTED PASSWORD',
|
||||
postgres._run_psql.call_args[0][0][13]
|
||||
)
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0}))
|
||||
@ -287,14 +299,12 @@ class PostgresTestCase(TestCase):
|
||||
groups='test_groups',
|
||||
runas='foo'
|
||||
)
|
||||
call = postgres._run_psql.call_args[0][0]
|
||||
self.assertTrue(re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password '
|
||||
'--username testuser'
|
||||
' --host testhost --port testport'
|
||||
' --dbname maint_test -c (\'|\")CREATE ROLE (\\\\)?"testuser(\\\\)?"',
|
||||
call))
|
||||
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
call = postgres._run_psql.call_args[0][0][13]
|
||||
self.assertTrue(re.match('CREATE ROLE "testuser"', call))
|
||||
for i in (
|
||||
'INHERIT NOCREATEDB NOCREATEROLE '
|
||||
'NOSUPERUSER NOREPLICATION LOGIN UNENCRYPTED PASSWORD'
|
||||
@ -379,21 +389,21 @@ class PostgresTestCase(TestCase):
|
||||
@patch('salt.modules.postgres.user_exists', Mock(return_value=True))
|
||||
def test_user_remove(self):
|
||||
postgres.user_remove(
|
||||
'test_user',
|
||||
user='test_user',
|
||||
host='test_host',
|
||||
port='test_port',
|
||||
'testuser',
|
||||
user='testuser',
|
||||
host='testhost',
|
||||
port='testport',
|
||||
maintenance_db='maint_db',
|
||||
password='test_password',
|
||||
password='testpassword',
|
||||
runas='foo'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
"/usr/bin/pgsql --no-align --no-readline --no-password "
|
||||
"--username test_user "
|
||||
"--host test_host --port test_port "
|
||||
"--dbname maint_db -c 'DROP ROLE test_user'",
|
||||
host='test_host', port='test_port', user='test_user',
|
||||
password='test_password', runas='foo')
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'DROP ROLE testuser'],
|
||||
host='testhost', port='testport', user='testuser',
|
||||
password='testpassword', runas='foo')
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
Mock(return_value={'retcode': 0}))
|
||||
@ -418,17 +428,18 @@ class PostgresTestCase(TestCase):
|
||||
groups='test_groups',
|
||||
runas='foo'
|
||||
)
|
||||
call_output = postgres._run_psql.call_args[0][0]
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password '
|
||||
'--username test_user '
|
||||
'--host test_host --port test_port --dbname test_maint '
|
||||
'-c [\'"]{0,1}ALTER ROLE (\\\\)?"test_username(\\\\)?" WITH INHERIT NOCREATEDB '
|
||||
'ALTER ROLE "test_username" WITH INHERIT NOCREATEDB '
|
||||
'NOCREATEROLE NOREPLICATION LOGIN '
|
||||
'UNENCRYPTED PASSWORD [\'"]{0,5}test_role_pass[\'"]{0,5};'
|
||||
' GRANT (\\\\)?"test_groups(\\\\)?" TO (\\\\)?"test_username(\\\\)?"[\'"]{0,1}',
|
||||
call_output)
|
||||
' GRANT "test_groups" TO "test_username"',
|
||||
postgres._run_psql.call_args[0][0][13]
|
||||
)
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
@ -453,15 +464,17 @@ class PostgresTestCase(TestCase):
|
||||
groups='test_groups',
|
||||
runas='foo'
|
||||
)
|
||||
call_output = postgres._run_psql.call_args[0][0]
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password --username test_user '
|
||||
'--host test_host --port test_port --dbname test_maint '
|
||||
'-c \'ALTER ROLE "test_username" WITH INHERIT NOCREATEDB '
|
||||
'ALTER ROLE "test_username" WITH INHERIT NOCREATEDB '
|
||||
'CREATEROLE NOREPLICATION LOGIN;'
|
||||
' GRANT "test_groups" TO "test_username"\'',
|
||||
call_output)
|
||||
' GRANT "test_groups" TO "test_username"',
|
||||
postgres._run_psql.call_args[0][0][13]
|
||||
)
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
@ -487,16 +500,17 @@ class PostgresTestCase(TestCase):
|
||||
groups='test_groups',
|
||||
runas='foo'
|
||||
)
|
||||
call_output = postgres._run_psql.call_args[0][0]
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password '
|
||||
'--username test_user '
|
||||
'--host test_host --port test_port --dbname test_maint '
|
||||
'-c \'ALTER ROLE "test_username" WITH INHERIT NOCREATEDB '
|
||||
'ALTER ROLE "test_username" WITH INHERIT NOCREATEDB '
|
||||
'CREATEROLE NOREPLICATION LOGIN NOPASSWORD;'
|
||||
' GRANT "test_groups" TO "test_username"\'',
|
||||
call_output)
|
||||
' GRANT "test_groups" TO "test_username"',
|
||||
postgres._run_psql.call_args[0][0][13]
|
||||
)
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
@ -522,18 +536,19 @@ class PostgresTestCase(TestCase):
|
||||
groups='test_groups',
|
||||
runas='foo'
|
||||
)
|
||||
call_output = postgres._run_psql.call_args[0][0]
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password '
|
||||
'--username test_user '
|
||||
'--host test_host --port test_port --dbname test_maint '
|
||||
'-c [\'"]{0,1}ALTER ROLE (\\\\)?"test_username(\\\\)?" WITH INHERIT NOCREATEDB '
|
||||
'ALTER ROLE "test_username" WITH INHERIT NOCREATEDB '
|
||||
'CREATEROLE NOREPLICATION LOGIN '
|
||||
'ENCRYPTED PASSWORD '
|
||||
'[\'"]{0,5}md531c27e68d3771c392b52102c01be1da1[\'"]{0,5}'
|
||||
'; GRANT (\\\\)?"test_groups(\\\\)?" TO (\\\\)?"test_username(\\\\)?"[\'"]{0,1}',
|
||||
call_output)
|
||||
'; GRANT "test_groups" TO "test_username"',
|
||||
postgres._run_psql.call_args[0][0][13]
|
||||
)
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres._run_psql',
|
||||
@ -547,14 +562,16 @@ class PostgresTestCase(TestCase):
|
||||
password='test_pass',
|
||||
runas='foo'
|
||||
)
|
||||
call_output = postgres._run_psql.call_args[0][0]
|
||||
self.assertTrue(re.match(
|
||||
'/usr/bin/pgsql --no-align --no-readline --no-password '
|
||||
'--username test_user '
|
||||
'--host test_host --port test_port '
|
||||
'--dbname test_maint '
|
||||
'-c (\'|\")SELECT setting FROM pg_catalog.pg_settings',
|
||||
call_output))
|
||||
# postgres._run_psql.call_args[0][0] will contain the list of CLI args.
|
||||
# The first 13 elements of this list are initial args used in all (or
|
||||
# virtually all) commands run through _run_psql(), so the actual SQL
|
||||
# query will be in the 14th argument.
|
||||
self.assertTrue(
|
||||
re.match(
|
||||
'SELECT setting FROM pg_catalog.pg_settings',
|
||||
postgres._run_psql.call_args[0][0][13]
|
||||
)
|
||||
)
|
||||
|
||||
@patch('salt.modules.postgres.psql_query',
|
||||
Mock(return_value=[{'extname': "foo", 'extversion': "1"}]))
|
||||
@ -784,21 +801,21 @@ class PostgresTestCase(TestCase):
|
||||
@patch('salt.modules.postgres.schema_exists', Mock(return_value=False))
|
||||
def test_schema_create(self):
|
||||
postgres.schema_create(
|
||||
'test_db',
|
||||
'test_schema',
|
||||
'maint_db',
|
||||
'testschema',
|
||||
user='user',
|
||||
db_host='test_host',
|
||||
db_port='test_port',
|
||||
db_user='test_user',
|
||||
db_password='test_password'
|
||||
db_host='testhost',
|
||||
db_port='testport',
|
||||
db_user='testuser',
|
||||
db_password='testpassword'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
"/usr/bin/pgsql --no-align --no-readline --no-password "
|
||||
"--username test_user "
|
||||
"--host test_host --port test_port "
|
||||
"--dbname test_db -c 'CREATE SCHEMA test_schema'",
|
||||
host='test_host', port='test_port',
|
||||
password='test_password', user='test_user', runas='user')
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'CREATE SCHEMA testschema'],
|
||||
host='testhost', port='testport',
|
||||
password='testpassword', user='testuser', runas='user')
|
||||
|
||||
@patch('salt.modules.postgres.schema_exists', Mock(return_value=True))
|
||||
def test_schema_create2(self):
|
||||
@ -817,21 +834,21 @@ class PostgresTestCase(TestCase):
|
||||
@patch('salt.modules.postgres.schema_exists', Mock(return_value=True))
|
||||
def test_schema_remove(self):
|
||||
postgres.schema_remove(
|
||||
'test_db',
|
||||
'test_schema',
|
||||
'maint_db',
|
||||
'testschema',
|
||||
user='user',
|
||||
db_host='test_host',
|
||||
db_port='test_port',
|
||||
db_user='test_user',
|
||||
db_password='test_password'
|
||||
db_host='testhost',
|
||||
db_port='testport',
|
||||
db_user='testuser',
|
||||
db_password='testpassword'
|
||||
)
|
||||
postgres._run_psql.assert_called_once_with(
|
||||
"/usr/bin/pgsql --no-align --no-readline --no-password "
|
||||
"--username test_user "
|
||||
"--host test_host --port test_port "
|
||||
"--dbname test_db -c 'DROP SCHEMA test_schema'",
|
||||
host='test_host', port='test_port',
|
||||
password='test_password', user='test_user', runas='user')
|
||||
['/usr/bin/pgsql', '--no-align', '--no-readline',
|
||||
'--no-password', '--username', 'testuser', '--host',
|
||||
'testhost', '--port', 'testport', '--dbname', 'maint_db',
|
||||
'-c', 'DROP SCHEMA testschema'],
|
||||
host='testhost', port='testport',
|
||||
password='testpassword', user='testuser', runas='user')
|
||||
|
||||
@patch('salt.modules.postgres.schema_exists', Mock(return_value=False))
|
||||
def test_schema_remove2(self):
|
||||
|
@ -42,17 +42,17 @@ class PwUserTestCase(TestCase):
|
||||
Test for adding a user
|
||||
'''
|
||||
with patch.dict(pw_user.__grains__, {'os_family': 'RedHat'}):
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': 'salt'})
|
||||
with patch.dict(pw_user.__salt__, {'cmd.run_all': mock}):
|
||||
mock = MagicMock(return_value=0)
|
||||
with patch.dict(pw_user.__salt__, {'cmd.retcode': mock}):
|
||||
self.assertTrue(pw_user.add('a'))
|
||||
|
||||
def test_delete(self):
|
||||
'''
|
||||
Test for deleting a user
|
||||
'''
|
||||
mock = MagicMock(return_value={'retcode': 0})
|
||||
with patch.dict(pw_user.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertTrue(pw_user.delete('A'), 1)
|
||||
mock = MagicMock(return_value=0)
|
||||
with patch.dict(pw_user.__salt__, {'cmd.retcode': mock}):
|
||||
self.assertTrue(pw_user.delete('A'))
|
||||
|
||||
def test_getent(self):
|
||||
'''
|
||||
|
@ -73,7 +73,7 @@ class RaetPublishTestCase(TestCase):
|
||||
with patch.object(salt.transport.Channel, 'factory',
|
||||
MagicMock(return_value=MockFactory())):
|
||||
self.assertEqual(raet_publish.runner(1),
|
||||
'1 runner publish timed out')
|
||||
'\'1\' runner publish timed out')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -122,26 +122,6 @@ class RbenvTestCase(TestCase):
|
||||
with patch.object(rbenv, '_rbenv_exec', return_value=None):
|
||||
self.assertTrue(rbenv.rehash())
|
||||
|
||||
def test_do(self):
|
||||
'''
|
||||
Test for execute a ruby command with rbenv's shims from
|
||||
the user or the system.
|
||||
'''
|
||||
with patch.object(rbenv, '_rbenv_path', return_value='A'):
|
||||
with patch.dict(rbenv.__salt__,
|
||||
{'cmd.run_all':
|
||||
MagicMock(return_value={'retcode': 0,
|
||||
'stdout': 'stdout'})}):
|
||||
with patch.object(rbenv, 'rehash', return_value=None):
|
||||
self.assertEqual(rbenv.do(), 'stdout')
|
||||
|
||||
with patch.dict(rbenv.__salt__,
|
||||
{'cmd.run_all':
|
||||
MagicMock(return_value={'retcode': 1,
|
||||
'stdout': 'stdout'})}):
|
||||
with patch.object(rbenv, 'rehash', return_value=None):
|
||||
self.assertFalse(rbenv.do(), 'stdout')
|
||||
|
||||
def test_do_with_ruby(self):
|
||||
'''
|
||||
Test for execute a ruby command with rbenv's shims using a
|
||||
|
@ -19,8 +19,7 @@ ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.modules import rsync
|
||||
from salt.exceptions import CommandExecutionError
|
||||
import os
|
||||
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
||||
|
||||
# Globals
|
||||
rsync.__salt__ = {}
|
||||
@ -37,13 +36,13 @@ class RsyncTestCase(TestCase):
|
||||
'''
|
||||
with patch.dict(rsync.__salt__, {'config.option':
|
||||
MagicMock(return_value=False)}):
|
||||
self.assertRaises(CommandExecutionError, rsync.rsync, False, False)
|
||||
self.assertRaises(SaltInvocationError, rsync.rsync, '', '')
|
||||
|
||||
with patch.dict(rsync.__salt__,
|
||||
{'config.option': MagicMock(return_value='A'),
|
||||
'cmd.run_all': MagicMock(side_effect=[IOError('f'),
|
||||
'cmd.run': MagicMock(side_effect=[IOError('f'),
|
||||
'A'])}):
|
||||
with patch.object(rsync, '_check', return_value='A'):
|
||||
with patch.object(rsync, '_check', return_value=['A']):
|
||||
self.assertRaises(CommandExecutionError, rsync.rsync, 'a', 'b')
|
||||
|
||||
self.assertEqual(rsync.rsync('src', 'dst'), 'A')
|
||||
@ -52,25 +51,11 @@ class RsyncTestCase(TestCase):
|
||||
'''
|
||||
Test for return rsync version
|
||||
'''
|
||||
mock = MagicMock(side_effect=[IOError('f'), {'stdout': 'A B C\n'}])
|
||||
with patch.dict(rsync.__salt__, {'cmd.run_all': mock}):
|
||||
mock = MagicMock(side_effect=[IOError('f'), 'A B C\n'])
|
||||
with patch.dict(rsync.__salt__, {'cmd.run_stdout': mock}):
|
||||
self.assertRaises(CommandExecutionError, rsync.version)
|
||||
|
||||
self.assertEqual(rsync.version(), {'stdout': 'C'})
|
||||
|
||||
def test_config(self):
|
||||
'''
|
||||
Test for return rsync config
|
||||
'''
|
||||
mock_file = MagicMock(side_effect=[False, True, True])
|
||||
with patch.object(os.path, 'isfile', mock_file):
|
||||
self.assertRaises(CommandExecutionError, rsync.config)
|
||||
|
||||
mock = MagicMock(side_effect=[IOError('f'), 'A'])
|
||||
with patch.dict(rsync.__salt__, {'cmd.run_all': mock}):
|
||||
self.assertRaises(CommandExecutionError, rsync.config)
|
||||
|
||||
self.assertEqual(rsync.config('confile'), 'A')
|
||||
self.assertEqual(rsync.version(), 'C')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -22,19 +22,27 @@ rvm.__salt__ = {
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class TestRvmModule(TestCase):
|
||||
|
||||
def test__rvm(self):
|
||||
def test_rvm(self):
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
with patch.dict(rvm.__salt__, {'cmd.run_all': mock}):
|
||||
rvm._rvm('install', '1.9.3')
|
||||
rvm._rvm(['install', '1.9.3'])
|
||||
mock.assert_called_once_with(
|
||||
'/usr/local/rvm/bin/rvm install 1.9.3', runas=None, cwd=None
|
||||
['/usr/local/rvm/bin/rvm', 'install', '1.9.3'],
|
||||
runas=None,
|
||||
cwd=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test__rvm_do(self):
|
||||
def test_rvm_do(self):
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': 'stdout'})
|
||||
with patch.dict(rvm.__salt__, {'cmd.run_all': mock}):
|
||||
rvm._rvm_do('1.9.3', 'gemset list')
|
||||
mock.assert_called_once_with('/usr/local/rvm/bin/rvm 1.9.3 do gemset list', runas=None, cwd=None)
|
||||
rvm._rvm_do('1.9.3', ['gemset', 'list'])
|
||||
mock.assert_called_once_with(
|
||||
['/usr/local/rvm/bin/rvm', '1.9.3', 'do', 'gemset', 'list'],
|
||||
runas=None,
|
||||
cwd=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_install(self):
|
||||
mock = MagicMock(return_value={'retcode': 0})
|
||||
@ -45,8 +53,20 @@ class TestRvmModule(TestCase):
|
||||
def test_install_ruby_nonroot(self):
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': 'stdout'})
|
||||
expected = [
|
||||
call('/usr/local/rvm/bin/rvm autolibs disable 2.0.0', runas='rvm', cwd=None),
|
||||
call('/usr/local/rvm/bin/rvm install --disable-binary 2.0.0', runas='rvm', cwd=None)]
|
||||
call(
|
||||
['/usr/local/rvm/bin/rvm', 'autolibs', 'disable', '2.0.0'],
|
||||
runas='rvm',
|
||||
cwd=None,
|
||||
python_shell=False
|
||||
),
|
||||
call(
|
||||
['/usr/local/rvm/bin/rvm', 'install',
|
||||
'--disable-binary', '2.0.0'],
|
||||
runas='rvm',
|
||||
cwd=None,
|
||||
python_shell=False
|
||||
)
|
||||
]
|
||||
with patch.dict(rvm.__salt__, {'cmd.run_all': mock}):
|
||||
rvm.install_ruby('2.0.0', runas='rvm')
|
||||
self.assertEqual(mock.call_args_list, expected)
|
||||
|
@ -310,7 +310,7 @@ class VirtualenvTestCase(TestCase):
|
||||
with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}):
|
||||
virtualenv_mod.create('/tmp/foo', prompt='\'PY\' Prompt')
|
||||
mock.assert_called_once_with(
|
||||
['virtualenv', '--prompt="\'PY\' Prompt"', '/tmp/foo'],
|
||||
['virtualenv', "--prompt=''PY' Prompt'", '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user