mirror of
https://github.com/valitydev/salt.git
synced 2024-11-06 08:35:21 +00:00
Merge branch '2016.11' into 'develop'
Conflicts: - doc/ref/configuration/master.rst - doc/topics/cloud/index.rst - salt/states/cron.py
This commit is contained in:
commit
8f80916432
@ -852,6 +852,10 @@
|
||||
# order will be used.
|
||||
#syndic_failover: random
|
||||
|
||||
# The number of seconds for the salt client to wait for additional syndics to
|
||||
# check in with their lists of expected minions before giving up.
|
||||
#syndic_wait: 5
|
||||
|
||||
|
||||
##### Peer Publish settings #####
|
||||
##########################################
|
||||
|
@ -11,6 +11,7 @@ Full list of Salt Cloud modules
|
||||
:template: autosummary.rst.tmpl
|
||||
|
||||
aliyun
|
||||
azurearm
|
||||
cloudstack
|
||||
digital_ocean
|
||||
dimensiondata
|
||||
|
6
doc/ref/clouds/all/salt.cloud.clouds.azureare.rst
Normal file
6
doc/ref/clouds/all/salt.cloud.clouds.azureare.rst
Normal file
@ -0,0 +1,6 @@
|
||||
==========================
|
||||
salt.cloud.clouds.azurearm
|
||||
==========================
|
||||
|
||||
.. automodule:: salt.cloud.clouds.azurearm
|
||||
:members:
|
@ -3151,6 +3151,20 @@ order will be used.
|
||||
|
||||
syndic_failover: random
|
||||
|
||||
.. conf_master:: syndic_wait
|
||||
|
||||
``syndic_wait``
|
||||
---------------
|
||||
|
||||
Default: ``5``
|
||||
|
||||
The number of seconds for the salt client to wait for additional syndics to
|
||||
check in with their lists of expected minions before giving up.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
syndic_wait: 5
|
||||
|
||||
.. conf_master:: syndic_forward_all_events
|
||||
|
||||
``syndic_forward_all_events``
|
||||
|
@ -105,7 +105,9 @@ Cloud Provider Specifics
|
||||
|
||||
Getting Started With Aliyun <aliyun>
|
||||
Getting Started With Azure <azure>
|
||||
Getting Started With Azure Arm <azurearm>
|
||||
Getting Started With DigitalOcean <digitalocean>
|
||||
Getting Started With Dimension Data <dimensiondata>
|
||||
Getting Started With EC2 <aws>
|
||||
Getting Started With GoGrid <gogrid>
|
||||
Getting Started With Google Compute Engine <gce>
|
||||
@ -114,19 +116,19 @@ Cloud Provider Specifics
|
||||
Getting Started With LXC <lxc>
|
||||
Getting Started With Libvirt <libvirt>
|
||||
Getting Started With Linode <linode>
|
||||
Getting Started With LXC <lxc>
|
||||
Getting Started With OpenNebula <opennebula>
|
||||
Getting Started With OpenStack <openstack>
|
||||
Getting Started With Parallels <parallels>
|
||||
Getting Started With ProfitBricks <profitbricks>
|
||||
Getting Started With Proxmox <proxmox>
|
||||
Getting Started With Rackspace <rackspace>
|
||||
Getting Started With Saltify <saltify>
|
||||
Getting Started With Scaleway <scaleway>
|
||||
Getting Started With Saltify <saltify>
|
||||
Getting Started With SoftLayer <softlayer>
|
||||
Getting Started With Vexxhost <vexxhost>
|
||||
Getting Started With Virtualbox <virtualbox>
|
||||
Getting Started With VMware <vmware>
|
||||
Getting Started With vSphere <vsphere>
|
||||
|
||||
|
||||
Miscellaneous Options
|
||||
|
@ -168,6 +168,16 @@ daemon until the data reaches the Master or Syndic node that issued the command.
|
||||
Syndic wait
|
||||
===========
|
||||
|
||||
``syndic_wait`` is a master configuration file setting that specifies the number of
|
||||
seconds the Salt client should wait for additional syndics to check in with their
|
||||
lists of expected minions before giving up. This value defaults to ``5`` seconds.
|
||||
|
||||
The ``syndic_wait`` setting is necessary because the higher-level master does not
|
||||
have a way of knowing which minions are below the syndics. The higher-level master
|
||||
has its own list of expected minions and the masters below them have their own lists
|
||||
as well, so the Salt client does not how long to wait for all returns. The
|
||||
``syndic_wait`` option allows time for all minions to return to the Salt client.
|
||||
|
||||
.. note::
|
||||
|
||||
To reduce the amount of time the CLI waits for Minions to respond, install
|
||||
|
@ -1319,7 +1319,7 @@ def os_data():
|
||||
init_cmdline = fhr.read().replace('\x00', ' ').split()
|
||||
init_bin = salt.utils.which(init_cmdline[0])
|
||||
if init_bin is not None and init_bin.endswith('bin/init'):
|
||||
supported_inits = (six.b('upstart'), six.b('sysvinit'), six.b('systemd'), six.b('runit'))
|
||||
supported_inits = (six.b('upstart'), six.b('sysvinit'), six.b('systemd'))
|
||||
edge_len = max(len(x) for x in supported_inits) - 1
|
||||
try:
|
||||
buf_size = __opts__['file_buffer_size']
|
||||
@ -1349,6 +1349,8 @@ def os_data():
|
||||
)
|
||||
elif salt.utils.which('supervisord') in init_cmdline:
|
||||
grains['init'] = 'supervisord'
|
||||
elif init_cmdline == ['runit']:
|
||||
grains['init'] = 'runit'
|
||||
else:
|
||||
log.info(
|
||||
'Could not determine init system from command line: ({0})'
|
||||
|
@ -112,12 +112,11 @@ def show_current(name):
|
||||
|
||||
salt '*' alternatives.show_current editor
|
||||
'''
|
||||
alt_link_path = '/etc/alternatives/{0}'.format(name)
|
||||
try:
|
||||
return os.readlink(alt_link_path)
|
||||
return _read_link(name)
|
||||
except OSError:
|
||||
log.error(
|
||||
'alternatives: path {0} does not exist'.format(alt_link_path)
|
||||
'alternative: {0} does not exist'.format(name)
|
||||
)
|
||||
return False
|
||||
|
||||
@ -154,7 +153,10 @@ def check_installed(name, path):
|
||||
|
||||
salt '*' alternatives.check_installed name path
|
||||
'''
|
||||
return show_current(name) == path
|
||||
try:
|
||||
return _read_link(name) == path
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
|
||||
def install(name, link, path, priority):
|
||||
@ -224,3 +226,13 @@ def set_(name, path):
|
||||
if out['retcode'] > 0:
|
||||
return out['stderr']
|
||||
return out['stdout']
|
||||
|
||||
|
||||
def _read_link(name):
|
||||
'''
|
||||
Read the link from /etc/alternatives
|
||||
|
||||
Throws an OSError if the link does not exist
|
||||
'''
|
||||
alt_link_path = '/etc/alternatives/{0}'.format(name)
|
||||
return os.readlink(alt_link_path)
|
||||
|
@ -966,6 +966,9 @@ def is_encrypted(name, clean=False, saltenv='base'):
|
||||
Returns ``True`` if the zip archive is password-protected, ``False`` if
|
||||
not. If the specified file is not a ZIP archive, an error will be raised.
|
||||
|
||||
name
|
||||
The path / URL of the archive to check.
|
||||
|
||||
clean : False
|
||||
Set this value to ``True`` to delete the path referred to by ``name``
|
||||
once the contents have been listed. This option should be used with
|
||||
@ -982,6 +985,7 @@ def is_encrypted(name, clean=False, saltenv='base'):
|
||||
|
||||
salt '*' archive.is_encrypted /path/to/myfile.zip
|
||||
salt '*' archive.is_encrypted salt://foo.zip
|
||||
salt '*' archive.is_encrypted salt://foo.zip saltenv=dev
|
||||
salt '*' archive.is_encrypted https://domain.tld/myfile.zip clean=True
|
||||
salt '*' archive.is_encrypted ftp://10.1.2.3/foo.zip
|
||||
'''
|
||||
|
@ -255,6 +255,7 @@ def list_(narrow=None,
|
||||
cmd.extend(['-source', source])
|
||||
if local_only:
|
||||
cmd.extend(['-localonly'])
|
||||
cmd.extend(['-limitoutput'])
|
||||
|
||||
result = __salt__['cmd.run_all'](cmd, python_shell=False)
|
||||
|
||||
@ -264,7 +265,7 @@ def list_(narrow=None,
|
||||
raise CommandExecutionError(err)
|
||||
|
||||
ret = {}
|
||||
pkg_re = re.compile(r'(\S+)\s+(\S+)')
|
||||
pkg_re = re.compile(r'(\S+)\|(\S+)')
|
||||
for line in result['stdout'].split('\n'):
|
||||
if line.startswith("No packages"):
|
||||
return ret
|
||||
|
@ -5887,11 +5887,19 @@ def sls_build(name, base='opensuse/python', mods=None, saltenv='base',
|
||||
.. versionadded:: 2016.11.0
|
||||
'''
|
||||
|
||||
create_kwargs = salt.utils.clean_kwargs(**copy.deepcopy(kwargs))
|
||||
for key in ('image', 'name', 'cmd', 'interactive', 'tty'):
|
||||
try:
|
||||
del create_kwargs[key]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
# start a new container
|
||||
ret = __salt__['dockerng.create'](image=base,
|
||||
name=name,
|
||||
cmd='sleep infinity',
|
||||
interactive=True, tty=True)
|
||||
interactive=True, tty=True,
|
||||
**create_kwargs)
|
||||
id_ = ret['Id']
|
||||
try:
|
||||
__salt__['dockerng.start'](id_)
|
||||
|
@ -182,7 +182,7 @@ def send_msg_multi(message,
|
||||
password = creds.get('xmpp.password')
|
||||
|
||||
xmpp = SendMsgBot.create_multi(
|
||||
jid, password, message, recipients=recipients, rooms=rooms)
|
||||
jid, password, message, recipients=recipients, rooms=rooms, nick=nick)
|
||||
|
||||
if rooms:
|
||||
xmpp.register_plugin('xep_0045') # MUC plugin
|
||||
|
@ -1906,7 +1906,7 @@ class State(object):
|
||||
Check if the low data chunk should send a failhard signal
|
||||
'''
|
||||
tag = _gen_tag(low)
|
||||
if self.opts['test']:
|
||||
if self.opts.get('test', False):
|
||||
return False
|
||||
if (low.get('failhard', False) or self.opts['failhard']
|
||||
and tag in running):
|
||||
|
@ -141,9 +141,72 @@ def extracted(name,
|
||||
|
||||
Ensure that an archive is extracted to a specific directory.
|
||||
|
||||
.. important::
|
||||
**Changes for 2016.11.0**
|
||||
|
||||
In earlier releases, this state would rely on the ``if_missing``
|
||||
argument to determine whether or not the archive needed to be
|
||||
extracted. When this argument was not passed, then the state would just
|
||||
assume ``if_missing`` is the same as the ``name`` argument (i.e. the
|
||||
parent directory into which the archive would be extracted).
|
||||
|
||||
This caused a number of annoyances. One such annoyance was the need to
|
||||
know beforehand a path that would result from the extraction of the
|
||||
archive, and setting ``if_missing`` to that directory, like so:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
extract_myapp:
|
||||
archive.extracted:
|
||||
- name: /var/www
|
||||
- source: salt://apps/src/myapp-16.2.4.tar.gz
|
||||
- user: www
|
||||
- group: www
|
||||
- if_missing: /var/www/myapp-16.2.4
|
||||
|
||||
If ``/var/www`` already existed, this would effectively make
|
||||
``if_missing`` a required argument, just to get Salt to extract the
|
||||
archive.
|
||||
|
||||
Some users worked around this by adding the top-level directory of the
|
||||
archive to the end of the ``name`` argument, and then used ``--strip``
|
||||
or ``--strip-components`` to remove that top-level dir when extracting:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
extract_myapp:
|
||||
archive.extracted:
|
||||
- name: /var/www/myapp-16.2.4
|
||||
- source: salt://apps/src/myapp-16.2.4.tar.gz
|
||||
- user: www
|
||||
- group: www
|
||||
- tar_options: --strip-components=1
|
||||
|
||||
With the rewrite for 2016.11.0, these workarounds are no longer
|
||||
necessary. ``if_missing`` is still a supported argument, but it is no
|
||||
longer required. The equivalent SLS in 2016.11.0 would be:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
extract_myapp:
|
||||
archive.extracted:
|
||||
- name: /var/www
|
||||
- source: salt://apps/src/myapp-16.2.4.tar.gz
|
||||
- user: www
|
||||
- group: www
|
||||
|
||||
Salt now uses a function called :py:func:`archive.list
|
||||
<salt.modules.archive.list>` to get a list of files/directories in the
|
||||
archive. Using this information, the state can now check the minion to
|
||||
see if any paths are missing, and know whether or not the archive needs
|
||||
to be extracted. This makes the ``if_missing`` argument unnecessary in
|
||||
most use cases.
|
||||
|
||||
.. important::
|
||||
**ZIP Archive Handling**
|
||||
|
||||
*Note: this information applies to 2016.11.0 and later.*
|
||||
|
||||
Salt has two different functions for extracting ZIP archives:
|
||||
|
||||
1. :py:func:`archive.unzip <salt.modules.archive.unzip>`, which uses
|
||||
@ -183,18 +246,6 @@ def extracted(name,
|
||||
Therefore, if ``use_cmd_unzip`` is specified and set to ``False``,
|
||||
and ``options`` is also set, the state will not proceed.
|
||||
|
||||
- *Password-protected ZIP Archives* (only supported by
|
||||
:py:func:`archive.unzip <salt.modules.archive.unzip>`) -
|
||||
:py:func:`archive.cmd_unzip <salt.modules.archive.cmd_unzip>` is not
|
||||
be permitted to extract password-protected ZIP archives, as
|
||||
attempting to do so will cause the unzip command to block on user
|
||||
input. The :py:func:`archive.is_encrypted
|
||||
<salt.modules.archive.unzip>` function will be used to determine if
|
||||
the archive is password-protected. If it is, then the ``password``
|
||||
argument will be required for the state to proceed. If
|
||||
``use_cmd_unzip`` is specified and set to ``True``, then the state
|
||||
will not proceed.
|
||||
|
||||
- *Permissions* - Due to an `upstream bug in Python`_, permissions are
|
||||
not preserved when the zipfile_ module is used to extract an archive.
|
||||
As of the 2016.11.0 release, :py:func:`archive.unzip
|
||||
@ -313,6 +364,11 @@ def extracted(name,
|
||||
**For ZIP archives only.** Password used for extraction.
|
||||
|
||||
.. versionadded:: 2016.3.0
|
||||
.. versionchanged:: 2016.11.0
|
||||
The newly-added :py:func:`archive.is_encrypted
|
||||
<salt.modules.archive.is_encrypted>` function will be used to
|
||||
determine if the archive is password-protected. If it is, then the
|
||||
``password`` argument will be required for the state to proceed.
|
||||
|
||||
options
|
||||
**For tar and zip archives only.** This option can be used to specify
|
||||
|
@ -72,7 +72,7 @@ def installed(name, version=None, source=None, force=False, pre_versions=False,
|
||||
'comment': ''}
|
||||
|
||||
# Determine if the package is installed
|
||||
if name not in __salt__['cmd.run']('choco list --local-only'):
|
||||
if name not in __salt__['cmd.run']('choco list --local-only --limit-output'):
|
||||
ret['changes'] = {'name': '{0} will be installed'.format(name)}
|
||||
elif force:
|
||||
ret['changes'] = {'name': '{0} is already installed but will reinstall'
|
||||
@ -150,7 +150,7 @@ def uninstalled(name, version=None, uninstall_args=None, override_args=False):
|
||||
'comment': ''}
|
||||
|
||||
# Determine if package is installed
|
||||
if name in __salt__['cmd.run']('choco list --local-only'):
|
||||
if name in __salt__['cmd.run']('choco list --local-only --limit-output'):
|
||||
ret['changes'] = {'name': '{0} will be removed'.format(name)}
|
||||
else:
|
||||
ret['comment'] = 'The package {0} is not installed'.format(name)
|
||||
|
@ -510,7 +510,7 @@ def file(name,
|
||||
Overrides the default backup mode for the user's crontab.
|
||||
'''
|
||||
# Initial set up
|
||||
mode = salt.utils.normalize_mode('0600')
|
||||
mode = '0600'
|
||||
|
||||
try:
|
||||
group = __salt__['user.info'](user)['groups'][0]
|
||||
|
@ -78,8 +78,7 @@ class AlternativesTestCase(TestCase):
|
||||
os_readlink_mock.side_effect = OSError('Hell was not found!!!')
|
||||
self.assertFalse(alternatives.show_current('hell'))
|
||||
os_readlink_mock.assert_called_with('/etc/alternatives/hell')
|
||||
self.assertIn('ERROR:alternatives: path /etc/alternatives/hell '
|
||||
'does not exist',
|
||||
self.assertIn('ERROR:alternative: hell does not exist',
|
||||
handler.messages)
|
||||
|
||||
@patch('os.readlink')
|
||||
|
Loading…
Reference in New Issue
Block a user