mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Merge branch '2014.7' into develop
Conflicts: salt/modules/virtualenv_mod.py salt/states/network.py salt/utils/parsers.py
This commit is contained in:
commit
3d73816507
@ -29,13 +29,13 @@ for :doc:`Cobbler <../../ref/tops/all/salt.tops.cobbler>` or:
|
||||
|
||||
for :doc:`Reclass <../../ref/tops/all/salt.tops.reclass_adapter>`.
|
||||
|
||||
It's also possible to create custom master_tops modules. These modules must go
|
||||
It's also possible to create custom master_tops modules. These modules must go
|
||||
in a subdirectory called `tops` in the `extension_modules` directory.
|
||||
The `extension_modules` directory is not defined by default (the
|
||||
default `/srv/salt/_modules` will NOT work as of this release)
|
||||
|
||||
Custom tops modules are written like any other execution module, see the source
|
||||
for the two modules above for examples of fully functional ones. Below is
|
||||
for the two modules above for examples of fully functional ones. Below is
|
||||
a degenerate example:
|
||||
|
||||
/etc/salt/master:
|
||||
@ -48,7 +48,7 @@ a degenerate example:
|
||||
|
||||
/srv/salt/modules/tops/customtop.py:
|
||||
|
||||
.. code-block: python
|
||||
.. code-block:: python
|
||||
|
||||
import logging
|
||||
import sys
|
||||
@ -67,7 +67,7 @@ a degenerate example:
|
||||
|
||||
`salt minion state.show_top` should then display something like:
|
||||
|
||||
.. code-block: bash
|
||||
.. code-block:: bash
|
||||
|
||||
$ salt minion state.show_top
|
||||
|
||||
@ -75,5 +75,3 @@ a degenerate example:
|
||||
----------
|
||||
base:
|
||||
- test
|
||||
|
||||
|
||||
|
@ -9,5 +9,7 @@ Version 2014.7.1 is a bugfix release for :doc:`2014.7.0
|
||||
|
||||
- Fixed gitfs serving symlinks in :mod:`file.recurse
|
||||
<salt.states.file.recurse>` states (:issue:`17700`)
|
||||
- Fix holding of multiple packages (YUM) when combined with version pinning
|
||||
- Fixed holding of multiple packages (YUM) when combined with version pinning
|
||||
(:issue:`18468`)
|
||||
- Fixed use of Jinja templates in masterless mode with non-roots fileserver
|
||||
backend (:issue:`17963`)
|
||||
|
@ -138,6 +138,23 @@ def clean_expired_tokens(opts):
|
||||
pass
|
||||
|
||||
|
||||
def clean_pub_auth(opts):
|
||||
try:
|
||||
auth_cache = os.path.join(opts['cachedir'], 'publish_auth')
|
||||
if not os.path.exists(auth_cache):
|
||||
return
|
||||
else:
|
||||
for (dirpath, dirnames, filenames) in os.walkpath(auth_cache):
|
||||
for auth_file in filenames:
|
||||
auth_file_path = os.path.join(dirpath, auth_file)
|
||||
if not os.path.isfile(auth_file_path):
|
||||
continue
|
||||
if os.path.getmtime(auth_file_path) - time.time() > opts['keep_jobs']:
|
||||
os.remove(auth_file_path)
|
||||
except (IOError, OSError):
|
||||
log.error('Unable to delete pub auth file')
|
||||
|
||||
|
||||
def clean_old_jobs(opts):
|
||||
'''
|
||||
Clean out the old jobs from the job cache
|
||||
|
@ -190,6 +190,8 @@ class Maintenance(multiprocessing.Process):
|
||||
last = int(time.time())
|
||||
# Clean out the fileserver backend cache
|
||||
salt.daemons.masterapi.clean_fsbackend(self.opts)
|
||||
# Clean out pub auth
|
||||
salt.daemons.masterapi.clean_pub_auth(self.opts)
|
||||
|
||||
old_present = set()
|
||||
while True:
|
||||
|
@ -958,8 +958,8 @@ def list_pkgs(versions_as_list=False,
|
||||
return ret
|
||||
|
||||
ret = {'installed': {}, 'removed': {}, 'purge_desired': {}}
|
||||
cmd = ('dpkg-query', '--showformat',
|
||||
'${Status} ${Package} ${Version} ${Architecture}\n', '-W')
|
||||
cmd = ['dpkg-query', '--showformat',
|
||||
'${Status} ${Package} ${Version} ${Architecture}\n', '-W']
|
||||
|
||||
out = __salt__['cmd.run_stdout'](
|
||||
cmd,
|
||||
|
@ -1089,6 +1089,8 @@ def _parse_bridge_opts(opts, iface):
|
||||
config = {}
|
||||
|
||||
if 'ports' in opts:
|
||||
if isinstance(opts['ports'], list):
|
||||
opts['ports'] = ','.join(opts['ports'])
|
||||
config.update({'ports': opts['ports']})
|
||||
|
||||
for opt in ['ageing', 'fd', 'gcint', 'hello', 'maxage']:
|
||||
@ -1539,7 +1541,7 @@ 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'
|
||||
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')
|
||||
|
@ -52,8 +52,8 @@ def _publish(
|
||||
|
||||
salt system.example.com publish.publish '*' cmd.run 'ls -la /tmp'
|
||||
'''
|
||||
if fun == 'publish.publish':
|
||||
log.info('Function name is \'publish.publish\'. Returning {}')
|
||||
if fun.startswith('publish.'):
|
||||
log.info('Cannot publish publish calls. Returning {}')
|
||||
return {}
|
||||
|
||||
if not isinstance(arg, list):
|
||||
@ -223,7 +223,8 @@ def full_data(tgt, fun, arg=None, expr_form='glob', returner='', timeout=5):
|
||||
expr_form=expr_form,
|
||||
returner=returner,
|
||||
timeout=timeout,
|
||||
form='full')
|
||||
form='full',
|
||||
wait=True)
|
||||
|
||||
|
||||
def runner(fun, arg=None, timeout=5):
|
||||
|
@ -10,10 +10,6 @@ import shutil
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
try:
|
||||
from shlex import quote as _cmd_quote # pylint: disable=E0611
|
||||
except ImportError:
|
||||
from pipes import quote as _cmd_quote
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
@ -130,7 +126,7 @@ def create(path,
|
||||
elif runas is not None and not user:
|
||||
user = str(runas)
|
||||
|
||||
cmd = [_cmd_quote(venv_bin)]
|
||||
cmd = [venv_bin]
|
||||
|
||||
if 'pyvenv' not in venv_bin:
|
||||
# ----- Stop the user if pyvenv only options are used --------------->
|
||||
@ -158,8 +154,10 @@ def create(path,
|
||||
)
|
||||
except ImportError:
|
||||
# Unable to import?? Let's parse the version from the console
|
||||
version_cmd = '{0} --version'.format(_cmd_quote(venv_bin))
|
||||
ret = __salt__['cmd.run_all'](version_cmd, runas=user)
|
||||
version_cmd = '{0} --version'.format(venv_bin)
|
||||
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}. '
|
||||
@ -187,7 +185,7 @@ def create(path,
|
||||
'Requested python ({0}) does not appear '
|
||||
'executable.'.format(python)
|
||||
)
|
||||
cmd.append('--python={0}'.format(_cmd_quote(python)))
|
||||
cmd.append('--python={0}'.format(python))
|
||||
if extra_search_dir is not None:
|
||||
if isinstance(extra_search_dir, string_types) and \
|
||||
extra_search_dir.strip() != '':
|
||||
@ -195,7 +193,7 @@ def create(path,
|
||||
e.strip() for e in extra_search_dir.split(',')
|
||||
]
|
||||
for entry in extra_search_dir:
|
||||
cmd.append('--extra-search-dir={0}'.format(_cmd_quote(entry)))
|
||||
cmd.append('--extra-search-dir={0}'.format(entry))
|
||||
if never_download is True:
|
||||
if virtualenv_version_info >= (1, 10):
|
||||
log.info(
|
||||
@ -207,7 +205,7 @@ def create(path,
|
||||
else:
|
||||
cmd.append('--never-download')
|
||||
if prompt is not None and prompt.strip() != '':
|
||||
cmd.append('--prompt={0!r}'.format(_cmd_quote(prompt)))
|
||||
cmd.append('--prompt={0!r}'.format(prompt))
|
||||
else:
|
||||
# venv module from the Python >= 3.3 standard library
|
||||
|
||||
@ -248,10 +246,10 @@ def create(path,
|
||||
cmd.append('--system-site-packages')
|
||||
|
||||
# Finally the virtualenv path
|
||||
cmd.append(_cmd_quote(path))
|
||||
cmd.append(path)
|
||||
|
||||
# Let's create the virtualenv
|
||||
ret = __salt__['cmd.run_all'](' '.join(cmd), runas=user)
|
||||
ret = __salt__['cmd.run_all'](cmd, runas=user, python_shell=False)
|
||||
if ret['retcode'] > 0:
|
||||
# Something went wrong. Let's bail out now!
|
||||
return ret
|
||||
@ -314,7 +312,7 @@ def get_site_packages(venv):
|
||||
raise salt.exceptions.CommandExecutionError(
|
||||
"Path does not appear to be a virtualenv: '{0}'".format(bin_path))
|
||||
|
||||
return __salt__['cmd.exec_code'](_cmd_quote(bin_path),
|
||||
return __salt__['cmd.exec_code'](bin_path,
|
||||
'from distutils import sysconfig; print sysconfig.get_python_lib()')
|
||||
|
||||
|
||||
@ -331,11 +329,12 @@ 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(_cmd_quote(python), _cmd_quote(tmppath)),
|
||||
'{0} {1}'.format(python, tmppath),
|
||||
runas=user,
|
||||
cwd=cwd,
|
||||
env={'VIRTUAL_ENV': cwd},
|
||||
use_vt=use_vt
|
||||
use_vt=use_vt,
|
||||
python_shell=False,
|
||||
)
|
||||
finally:
|
||||
os.remove(tmppath)
|
||||
|
@ -2,6 +2,9 @@
|
||||
'''
|
||||
Management of Mongodb users
|
||||
===========================
|
||||
|
||||
.. note::
|
||||
This module requires PyMongo to be installed.
|
||||
'''
|
||||
|
||||
# Define the module's virtual name
|
||||
|
@ -171,7 +171,6 @@ def mounted(name,
|
||||
+ "options changed"
|
||||
remount_result = __salt__['mount.remount'](real_name, device, mkmnt=mkmnt, fstype=fstype, opts=opts, user=user)
|
||||
ret['result'] = remount_result
|
||||
return ret
|
||||
if real_device not in device_list:
|
||||
# name matches but device doesn't - need to umount
|
||||
if __opts__['test']:
|
||||
|
@ -148,6 +148,7 @@ all interfaces are ignored unless specified.
|
||||
- proto: dhcp
|
||||
- bridge: br0
|
||||
- delay: 0
|
||||
- ports: eth4
|
||||
- bypassfirewall: True
|
||||
- use:
|
||||
- network: eth4
|
||||
@ -170,6 +171,10 @@ all interfaces are ignored unless specified.
|
||||
|
||||
.. versionadded:: Lithium
|
||||
|
||||
.. note::
|
||||
|
||||
When managing bridged interfaces on a Debian or Ubuntu based system, the
|
||||
ports argument is required. Red Hat systems will ignore the argument.
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
|
@ -42,6 +42,9 @@ try:
|
||||
BASE_MASTER_ROOTS_DIR,
|
||||
LOGS_DIR,
|
||||
PIDFILE_DIR,
|
||||
CLOUD_DIR,
|
||||
INSTALL_DIR,
|
||||
BOOTSTRAP,
|
||||
)
|
||||
except ImportError:
|
||||
# The installation time was not generated, let's define the default values
|
||||
|
@ -57,7 +57,8 @@ def build_pillar_data(options):
|
||||
Build a YAML formatted string to properly pass pillar data
|
||||
'''
|
||||
pillar = {'test_transport': options.test_transport,
|
||||
'cloud_only': options.cloud_only}
|
||||
'cloud_only': options.cloud_only,
|
||||
'with_coverage': options.test_without_coverage is False}
|
||||
if options.test_git_commit is not None:
|
||||
pillar['test_git_commit'] = options.test_git_commit
|
||||
if options.test_git_url is not None:
|
||||
@ -371,7 +372,8 @@ def run(opts):
|
||||
)
|
||||
|
||||
if opts.download_remote_reports:
|
||||
opts.download_coverage_report = vm_name
|
||||
if opts.test_without_coverage is False:
|
||||
opts.download_coverage_report = vm_name
|
||||
opts.download_unittest_reports = vm_name
|
||||
opts.download_packages = vm_name
|
||||
|
||||
@ -773,7 +775,8 @@ def run(opts):
|
||||
# Download unittest reports
|
||||
download_unittest_reports(opts)
|
||||
# Download coverage report
|
||||
download_coverage_report(opts)
|
||||
if opts.test_without_coverage is False:
|
||||
download_coverage_report(opts)
|
||||
|
||||
if opts.clean and 'JENKINS_SALTCLOUD_VM_NAME' not in os.environ:
|
||||
delete_vm(opts)
|
||||
@ -829,6 +832,12 @@ def parse():
|
||||
default='zeromq',
|
||||
choices=('zeromq', 'raet'),
|
||||
help='Set to raet to run integration tests with raet transport. Default: %default')
|
||||
parser.add_option(
|
||||
'--test-without-coverage',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Do not generate coverage reports'
|
||||
)
|
||||
parser.add_option(
|
||||
'--prep-sls',
|
||||
default='git.salt',
|
||||
@ -943,9 +952,10 @@ def parse():
|
||||
download_unittest_reports(options)
|
||||
parser.exit(0)
|
||||
|
||||
if options.download_coverage_report is not None and not options.test_git_commit:
|
||||
download_coverage_report(options)
|
||||
parser.exit(0)
|
||||
if options.test_without_coverage is False:
|
||||
if options.download_coverage_report is not None and not options.test_git_commit:
|
||||
download_coverage_report(options)
|
||||
parser.exit(0)
|
||||
|
||||
if options.download_remote_logs is not None and not options.test_git_commit:
|
||||
download_remote_logs(options)
|
||||
|
@ -50,8 +50,9 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', system_site_packages=True, distribute=True
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv --distribute --system-site-packages /tmp/foo',
|
||||
runas=None
|
||||
['virtualenv', '--distribute', '--system-site-packages', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
with TestsLoggingHandler() as handler:
|
||||
@ -66,8 +67,9 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', system_site_packages=True, distribute=True
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv --system-site-packages /tmp/foo',
|
||||
runas=None
|
||||
['virtualenv', '--system-site-packages', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
# Are we logging the deprecation information?
|
||||
@ -87,8 +89,9 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', never_download=True
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv --never-download /tmp/foo',
|
||||
runas=None
|
||||
['virtualenv', '--never-download', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
with TestsLoggingHandler() as handler:
|
||||
@ -102,8 +105,9 @@ class VirtualenvTestCase(TestCase):
|
||||
virtualenv_mod.create(
|
||||
'/tmp/foo', never_download=True
|
||||
)
|
||||
mock.assert_called_once_with('virtualenv /tmp/foo',
|
||||
runas=None)
|
||||
mock.assert_called_once_with(['virtualenv', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False)
|
||||
|
||||
# Are we logging the deprecation information?
|
||||
self.assertIn(
|
||||
@ -128,12 +132,13 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', extra_search_dir=extra_search_dirs
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv '
|
||||
'--extra-search-dir=/tmp/bar-1 '
|
||||
'--extra-search-dir=/tmp/bar-2 '
|
||||
'--extra-search-dir=/tmp/bar-3 '
|
||||
'/tmp/foo',
|
||||
runas=None
|
||||
['virtualenv',
|
||||
'--extra-search-dir=/tmp/bar-1',
|
||||
'--extra-search-dir=/tmp/bar-2',
|
||||
'--extra-search-dir=/tmp/bar-3',
|
||||
'/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
# Passing extra_search_dirs as comma separated list
|
||||
@ -143,12 +148,13 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', extra_search_dir=','.join(extra_search_dirs)
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv '
|
||||
'--extra-search-dir=/tmp/bar-1 '
|
||||
'--extra-search-dir=/tmp/bar-2 '
|
||||
'--extra-search-dir=/tmp/bar-3 '
|
||||
'/tmp/foo',
|
||||
runas=None
|
||||
['virtualenv',
|
||||
'--extra-search-dir=/tmp/bar-1',
|
||||
'--extra-search-dir=/tmp/bar-2',
|
||||
'--extra-search-dir=/tmp/bar-3',
|
||||
'/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_unapplicable_options(self):
|
||||
@ -253,8 +259,9 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', never_download=True
|
||||
)
|
||||
mock.assert_called_with(
|
||||
'virtualenv --never-download /tmp/foo',
|
||||
runas=None
|
||||
['virtualenv', '--never-download', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
# <---- virtualenv binary returns 1.9.1 as its version ----------
|
||||
|
||||
@ -268,8 +275,9 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', never_download=True
|
||||
)
|
||||
mock.assert_called_with(
|
||||
'virtualenv /tmp/foo',
|
||||
runas=None
|
||||
['virtualenv', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
# <---- virtualenv binary returns 1.10rc1 as its version --------
|
||||
|
||||
@ -281,8 +289,9 @@ class VirtualenvTestCase(TestCase):
|
||||
'/tmp/foo', python=sys.executable,
|
||||
)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv --python={0} /tmp/foo'.format(sys.executable),
|
||||
runas=None
|
||||
['virtualenv', '--python={0}'.format(sys.executable), '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_prompt_argument(self):
|
||||
@ -290,8 +299,9 @@ 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',
|
||||
runas=None
|
||||
['virtualenv', '--prompt=\'PY Prompt\'', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
# Now with some quotes on the mix
|
||||
@ -299,16 +309,18 @@ 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',
|
||||
runas=None
|
||||
['virtualenv', '--prompt="\'PY\' Prompt"', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
mock = MagicMock(return_value={'retcode': 0, 'stdout': ''})
|
||||
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',
|
||||
runas=None
|
||||
['virtualenv', '--prompt=\'"PY" Prompt\'', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_clear_argument(self):
|
||||
@ -316,7 +328,9 @@ class VirtualenvTestCase(TestCase):
|
||||
with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}):
|
||||
virtualenv_mod.create('/tmp/foo', clear=True)
|
||||
mock.assert_called_once_with(
|
||||
'virtualenv --clear /tmp/foo', runas=None
|
||||
['virtualenv', '--clear', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_upgrade_argument(self):
|
||||
@ -326,7 +340,9 @@ class VirtualenvTestCase(TestCase):
|
||||
with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}):
|
||||
virtualenv_mod.create('/tmp/foo', venv_bin='pyvenv', upgrade=True)
|
||||
mock.assert_called_once_with(
|
||||
'pyvenv --upgrade /tmp/foo', runas=None
|
||||
['pyvenv', '--upgrade', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
def test_symlinks_argument(self):
|
||||
@ -336,7 +352,9 @@ class VirtualenvTestCase(TestCase):
|
||||
with patch.dict(virtualenv_mod.__salt__, {'cmd.run_all': mock}):
|
||||
virtualenv_mod.create('/tmp/foo', venv_bin='pyvenv', symlinks=True)
|
||||
mock.assert_called_once_with(
|
||||
'pyvenv --symlinks /tmp/foo', runas=None
|
||||
['pyvenv', '--symlinks', '/tmp/foo'],
|
||||
runas=None,
|
||||
python_shell=False
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user