mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge pull request #42601 from rallytime/merge-2017.7
[2017.7] Merge forward from 2016.11 to 2017.7
This commit is contained in:
commit
e2dd443002
@ -405,6 +405,29 @@ similar to the following:
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
The ``__virtual__()`` function can return a ``True`` or ``False`` boolean, a tuple,
|
||||
or a string. If it returns a ``True`` value, this ``__virtualname__`` module-level
|
||||
attribute can be set as seen in the above example. This is the string that the module
|
||||
should be referred to as.
|
||||
|
||||
When ``__virtual__()`` returns a tuple, the first item should be a boolean and the
|
||||
second should be a string. This is typically done when the module should not load. The
|
||||
first value of the tuple is ``False`` and the second is the error message to display
|
||||
for why the module did not load.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only load if git exists on the system
|
||||
'''
|
||||
if salt.utils.which('git') is None:
|
||||
return (False,
|
||||
'The git execution module cannot be loaded: git unavailable.')
|
||||
else:
|
||||
return True
|
||||
|
||||
Documentation
|
||||
=============
|
||||
|
@ -75,7 +75,7 @@ The default location for the pillar is in /srv/pillar.
|
||||
|
||||
.. note::
|
||||
|
||||
The pillar location can be configured via the `pillar_roots` option inside
|
||||
The pillar location can be configured via the ``pillar_roots`` option inside
|
||||
the master configuration file. It must not be in a subdirectory of the state
|
||||
tree or file_roots. If the pillar is under file_roots, any pillar targeting
|
||||
can be bypassed by minions.
|
||||
@ -242,7 +242,7 @@ set in the minion's pillar, then the default of ``httpd`` will be used.
|
||||
.. note::
|
||||
|
||||
Under the hood, pillar is just a Python dict, so Python dict methods such
|
||||
as `get` and `items` can be used.
|
||||
as ``get`` and ``items`` can be used.
|
||||
|
||||
Pillar Makes Simple States Grow Easily
|
||||
======================================
|
||||
@ -303,6 +303,18 @@ Where the vimrc source location can now be changed via pillar:
|
||||
|
||||
Ensuring that the right vimrc is sent out to the correct minions.
|
||||
|
||||
The pillar top file must include a reference to the new sls pillar file:
|
||||
|
||||
``/srv/pillar/top.sls``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
base:
|
||||
'*':
|
||||
- pkg
|
||||
- edit.vim
|
||||
|
||||
|
||||
Setting Pillar Data on the Command Line
|
||||
=======================================
|
||||
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-call
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-cp
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-key
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-master
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -12,5 +12,4 @@ Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||
net stop salt-minion
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" -l debug
|
||||
|
||||
"%Python%" -E -s "%Script%" -l debug
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-run
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
"%Python%" -E -s "%Script%" %*
|
||||
|
@ -379,8 +379,7 @@ Section -Post
|
||||
WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
|
||||
|
||||
; Register the Salt-Minion Service
|
||||
nsExec::Exec "nssm.exe install salt-minion $INSTDIR\bin\python.exe $INSTDIR\bin\Scripts\salt-minion -c $INSTDIR\conf -l quiet"
|
||||
nsExec::Exec "nssm.exe set salt-minion AppEnvironmentExtra PYTHONHOME="
|
||||
nsExec::Exec "nssm.exe install salt-minion $INSTDIR\bin\python.exe -E -s $INSTDIR\bin\Scripts\salt-minion -c $INSTDIR\conf -l quiet"
|
||||
nsExec::Exec "nssm.exe set salt-minion Description Salt Minion from saltstack.com"
|
||||
nsExec::Exec "nssm.exe set salt-minion Start SERVICE_AUTO_START"
|
||||
nsExec::Exec "nssm.exe set salt-minion AppNoConsole 1"
|
||||
|
@ -1030,10 +1030,18 @@ def ssh_interface(vm_):
|
||||
Return the ssh_interface type to connect to. Either 'public_ips' (default)
|
||||
or 'private_ips'.
|
||||
'''
|
||||
return config.get_cloud_config_value(
|
||||
ret = config.get_cloud_config_value(
|
||||
'ssh_interface', vm_, __opts__, default='public_ips',
|
||||
search_global=False
|
||||
)
|
||||
if ret not in ('public_ips', 'private_ips'):
|
||||
log.warning((
|
||||
'Invalid ssh_interface: {0}. '
|
||||
'Allowed options are ("public_ips", "private_ips"). '
|
||||
'Defaulting to "public_ips".'
|
||||
).format(ret))
|
||||
ret = 'public_ips'
|
||||
return ret
|
||||
|
||||
|
||||
def get_ssh_gateway_config(vm_):
|
||||
|
@ -373,17 +373,18 @@ class AsyncAuth(object):
|
||||
loop_instance_map = AsyncAuth.instance_map[io_loop]
|
||||
|
||||
key = cls.__key(opts)
|
||||
if key not in loop_instance_map:
|
||||
auth = loop_instance_map.get(key)
|
||||
if auth is None:
|
||||
log.debug('Initializing new AsyncAuth for {0}'.format(key))
|
||||
# we need to make a local variable for this, as we are going to store
|
||||
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||
# references it-- this forces a reference while we return to the caller
|
||||
new_auth = object.__new__(cls)
|
||||
new_auth.__singleton_init__(opts, io_loop=io_loop)
|
||||
loop_instance_map[key] = new_auth
|
||||
auth = object.__new__(cls)
|
||||
auth.__singleton_init__(opts, io_loop=io_loop)
|
||||
loop_instance_map[key] = auth
|
||||
else:
|
||||
log.debug('Re-using AsyncAuth for {0}'.format(key))
|
||||
return loop_instance_map[key]
|
||||
return auth
|
||||
|
||||
@classmethod
|
||||
def __key(cls, opts, io_loop=None):
|
||||
@ -1009,14 +1010,15 @@ class SAuth(AsyncAuth):
|
||||
Only create one instance of SAuth per __key()
|
||||
'''
|
||||
key = cls.__key(opts)
|
||||
if key not in SAuth.instances:
|
||||
auth = SAuth.instances.get(key)
|
||||
if auth is None:
|
||||
log.debug('Initializing new SAuth for {0}'.format(key))
|
||||
new_auth = object.__new__(cls)
|
||||
new_auth.__singleton_init__(opts)
|
||||
SAuth.instances[key] = new_auth
|
||||
auth = object.__new__(cls)
|
||||
auth.__singleton_init__(opts)
|
||||
SAuth.instances[key] = auth
|
||||
else:
|
||||
log.debug('Re-using SAuth for {0}'.format(key))
|
||||
return SAuth.instances[key]
|
||||
return auth
|
||||
|
||||
@classmethod
|
||||
def __key(cls, opts, io_loop=None):
|
||||
|
@ -710,18 +710,21 @@ def check_hash(path, file_hash):
|
||||
|
||||
hash
|
||||
The hash to check against the file specified in the ``path`` argument.
|
||||
For versions 2016.11.4 and newer, the hash can be specified without an
|
||||
|
||||
.. versionchanged:: 2016.11.4
|
||||
|
||||
For this and newer versions the hash can be specified without an
|
||||
accompanying hash type (e.g. ``e138491e9d5b97023cea823fe17bac22``),
|
||||
but for earlier releases it is necessary to also specify the hash type
|
||||
in the format ``<hash_type>:<hash_value>`` (e.g.
|
||||
``md5:e138491e9d5b97023cea823fe17bac22``).
|
||||
in the format ``<hash_type>=<hash_value>`` (e.g.
|
||||
``md5=e138491e9d5b97023cea823fe17bac22``).
|
||||
|
||||
CLI Example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt '*' file.check_hash /etc/fstab e138491e9d5b97023cea823fe17bac22
|
||||
salt '*' file.check_hash /etc/fstab md5:e138491e9d5b97023cea823fe17bac22
|
||||
salt '*' file.check_hash /etc/fstab md5=e138491e9d5b97023cea823fe17bac22
|
||||
'''
|
||||
path = os.path.expanduser(path)
|
||||
|
||||
|
@ -216,7 +216,7 @@ def align_check(device, part_type, partition):
|
||||
'Invalid partition passed to partition.align_check'
|
||||
)
|
||||
|
||||
cmd = 'parted -m -s {0} align-check {1} {2}'.format(
|
||||
cmd = 'parted -m {0} align-check {1} {2}'.format(
|
||||
device, part_type, partition
|
||||
)
|
||||
out = __salt__['cmd.run'](cmd).splitlines()
|
||||
|
@ -135,6 +135,7 @@ def _safe_output(line):
|
||||
'''
|
||||
return not any([
|
||||
line.startswith('Listing') and line.endswith('...'),
|
||||
line.startswith('Listing') and '\t' not in line,
|
||||
'...done' in line,
|
||||
line.startswith('WARNING:')
|
||||
])
|
||||
|
@ -875,12 +875,26 @@ def set_wu_settings(level=None,
|
||||
Change Windows Update settings. If no parameters are passed, the current
|
||||
value will be returned.
|
||||
|
||||
Supported:
|
||||
- Windows Vista / Server 2008
|
||||
- Windows 7 / Server 2008R2
|
||||
- Windows 8 / Server 2012
|
||||
- Windows 8.1 / Server 2012R2
|
||||
|
||||
.. note:
|
||||
Microsoft began using the Unified Update Platform (UUP) starting with
|
||||
Windows 10 / Server 2016. The Windows Update settings have changed and
|
||||
the ability to 'Save' Windows Update settings has been removed. Windows
|
||||
Update settings are read-only. See MSDN documentation:
|
||||
https://msdn.microsoft.com/en-us/library/aa385829(v=vs.85).aspx
|
||||
|
||||
:param int level:
|
||||
Number from 1 to 4 indicating the update level:
|
||||
1. Never check for updates
|
||||
2. Check for updates but let me choose whether to download and install them
|
||||
3. Download updates but let me choose whether to install them
|
||||
4. Install updates automatically
|
||||
|
||||
:param bool recommended:
|
||||
Boolean value that indicates whether to include optional or recommended
|
||||
updates when a search for updates and installation of updates is
|
||||
@ -923,8 +937,28 @@ def set_wu_settings(level=None,
|
||||
salt '*' win_wua.set_wu_settings level=4 recommended=True featured=False
|
||||
|
||||
'''
|
||||
ret = {}
|
||||
ret['Success'] = True
|
||||
# The AutomaticUpdateSettings.Save() method used in this function does not
|
||||
# work on Windows 10 / Server 2016. It is called in throughout this function
|
||||
# like this:
|
||||
#
|
||||
# obj_au = win32com.client.Dispatch('Microsoft.Update.AutoUpdate')
|
||||
# obj_au_settings = obj_au.Settings
|
||||
# obj_au_settings.Save()
|
||||
#
|
||||
# The `Save()` method reports success but doesn't actually change anything.
|
||||
# Windows Update settings are read-only in Windows 10 / Server 2016. There's
|
||||
# a little blurb on MSDN that mentions this, but gives no alternative for
|
||||
# changing these settings in Windows 10 / Server 2016.
|
||||
#
|
||||
# https://msdn.microsoft.com/en-us/library/aa385829(v=vs.85).aspx
|
||||
#
|
||||
# Apparently the Windows Update framework in Windows Vista - Windows 8.1 has
|
||||
# been changed quite a bit in Windows 10 / Server 2016. It is now called the
|
||||
# Unified Update Platform (UUP). I haven't found an API or a Powershell
|
||||
# commandlet for working with the the UUP. Perhaps there will be something
|
||||
# forthcoming. The `win_lgpo` module might be an option for changing the
|
||||
# Windows Update settings using local group policy.
|
||||
ret = {'Success': True}
|
||||
|
||||
# Initialize the PyCom system
|
||||
pythoncom.CoInitialize()
|
||||
|
@ -250,15 +250,16 @@ class IPCClient(object):
|
||||
# FIXME
|
||||
key = str(socket_path)
|
||||
|
||||
if key not in loop_instance_map:
|
||||
client = loop_instance_map.get(key)
|
||||
if client is None:
|
||||
log.debug('Initializing new IPCClient for path: {0}'.format(key))
|
||||
new_client = object.__new__(cls)
|
||||
client = object.__new__(cls)
|
||||
# FIXME
|
||||
new_client.__singleton_init__(io_loop=io_loop, socket_path=socket_path)
|
||||
loop_instance_map[key] = new_client
|
||||
client.__singleton_init__(io_loop=io_loop, socket_path=socket_path)
|
||||
loop_instance_map[key] = client
|
||||
else:
|
||||
log.debug('Re-using IPCClient for {0}'.format(key))
|
||||
return loop_instance_map[key]
|
||||
return client
|
||||
|
||||
def __singleton_init__(self, socket_path, io_loop=None):
|
||||
'''
|
||||
|
@ -221,17 +221,18 @@ class AsyncTCPReqChannel(salt.transport.client.ReqChannel):
|
||||
loop_instance_map = cls.instance_map[io_loop]
|
||||
|
||||
key = cls.__key(opts, **kwargs)
|
||||
if key not in loop_instance_map:
|
||||
obj = loop_instance_map.get(key)
|
||||
if obj is None:
|
||||
log.debug('Initializing new AsyncTCPReqChannel for {0}'.format(key))
|
||||
# we need to make a local variable for this, as we are going to store
|
||||
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||
# references it-- this forces a reference while we return to the caller
|
||||
new_obj = object.__new__(cls)
|
||||
new_obj.__singleton_init__(opts, **kwargs)
|
||||
loop_instance_map[key] = new_obj
|
||||
obj = object.__new__(cls)
|
||||
obj.__singleton_init__(opts, **kwargs)
|
||||
loop_instance_map[key] = obj
|
||||
else:
|
||||
log.debug('Re-using AsyncTCPReqChannel for {0}'.format(key))
|
||||
return loop_instance_map[key]
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def __key(cls, opts, **kwargs):
|
||||
|
@ -80,28 +80,19 @@ class AsyncZeroMQReqChannel(salt.transport.client.ReqChannel):
|
||||
loop_instance_map = cls.instance_map[io_loop]
|
||||
|
||||
key = cls.__key(opts, **kwargs)
|
||||
if key not in loop_instance_map:
|
||||
obj = loop_instance_map.get(key)
|
||||
if obj is None:
|
||||
log.debug('Initializing new AsyncZeroMQReqChannel for {0}'.format(key))
|
||||
# we need to make a local variable for this, as we are going to store
|
||||
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||
# references it-- this forces a reference while we return to the caller
|
||||
new_obj = object.__new__(cls)
|
||||
new_obj.__singleton_init__(opts, **kwargs)
|
||||
loop_instance_map[key] = new_obj
|
||||
obj = object.__new__(cls)
|
||||
obj.__singleton_init__(opts, **kwargs)
|
||||
loop_instance_map[key] = obj
|
||||
log.trace('Inserted key into loop_instance_map id {0} for key {1} and process {2}'.format(id(loop_instance_map), key, os.getpid()))
|
||||
else:
|
||||
log.debug('Re-using AsyncZeroMQReqChannel for {0}'.format(key))
|
||||
try:
|
||||
return loop_instance_map[key]
|
||||
except KeyError:
|
||||
# In iterating over the loop_instance_map, we may have triggered
|
||||
# garbage collection. Therefore, the key is no longer present in
|
||||
# the map. Re-gen and add to map.
|
||||
log.debug('Initializing new AsyncZeroMQReqChannel due to GC for {0}'.format(key))
|
||||
new_obj = object.__new__(cls)
|
||||
new_obj.__singleton_init__(opts, **kwargs)
|
||||
loop_instance_map[key] = new_obj
|
||||
return loop_instance_map[key]
|
||||
return obj
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
cls = self.__class__
|
||||
|
Loading…
Reference in New Issue
Block a user