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 __virtualname__
|
||||||
return False
|
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
|
Documentation
|
||||||
=============
|
=============
|
||||||
|
@ -75,7 +75,7 @@ The default location for the pillar is in /srv/pillar.
|
|||||||
|
|
||||||
.. note::
|
.. 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
|
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
|
tree or file_roots. If the pillar is under file_roots, any pillar targeting
|
||||||
can be bypassed by minions.
|
can be bypassed by minions.
|
||||||
@ -242,7 +242,7 @@ set in the minion's pillar, then the default of ``httpd`` will be used.
|
|||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
Under the hood, pillar is just a Python dict, so Python dict methods such
|
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
|
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.
|
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
|
Setting Pillar Data on the Command Line
|
||||||
=======================================
|
=======================================
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt-call
|
Set Script=%SaltDir%\bin\Scripts\salt-call
|
||||||
|
|
||||||
:: Launch Script
|
:: 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
|
Set Script=%SaltDir%\bin\Scripts\salt-cp
|
||||||
|
|
||||||
:: Launch Script
|
:: 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
|
Set Script=%SaltDir%\bin\Scripts\salt-key
|
||||||
|
|
||||||
:: Launch Script
|
:: 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
|
Set Script=%SaltDir%\bin\Scripts\salt-master
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -12,5 +12,4 @@ Set Script=%SaltDir%\bin\Scripts\salt-minion
|
|||||||
net stop salt-minion
|
net stop salt-minion
|
||||||
|
|
||||||
:: Launch Script
|
:: 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
|
Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||||
|
|
||||||
:: Launch Script
|
:: 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
|
Set Script=%SaltDir%\bin\Scripts\salt-run
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -9,5 +9,4 @@ Set Python=%SaltDir%\bin\python.exe
|
|||||||
Set Script=%SaltDir%\bin\Scripts\salt
|
Set Script=%SaltDir%\bin\Scripts\salt
|
||||||
|
|
||||||
:: Launch Script
|
:: Launch Script
|
||||||
"%Python%" "%Script%" %*
|
"%Python%" -E -s "%Script%" %*
|
||||||
|
|
||||||
|
@ -379,8 +379,7 @@ Section -Post
|
|||||||
WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
|
WriteRegStr HKLM "${PRODUCT_MINION_REGKEY}" "Path" "$INSTDIR\bin\"
|
||||||
|
|
||||||
; Register the Salt-Minion Service
|
; 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 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 AppEnvironmentExtra PYTHONHOME="
|
|
||||||
nsExec::Exec "nssm.exe set salt-minion Description Salt Minion from saltstack.com"
|
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 Start SERVICE_AUTO_START"
|
||||||
nsExec::Exec "nssm.exe set salt-minion AppNoConsole 1"
|
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)
|
Return the ssh_interface type to connect to. Either 'public_ips' (default)
|
||||||
or 'private_ips'.
|
or 'private_ips'.
|
||||||
'''
|
'''
|
||||||
return config.get_cloud_config_value(
|
ret = config.get_cloud_config_value(
|
||||||
'ssh_interface', vm_, __opts__, default='public_ips',
|
'ssh_interface', vm_, __opts__, default='public_ips',
|
||||||
search_global=False
|
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_):
|
def get_ssh_gateway_config(vm_):
|
||||||
|
@ -373,17 +373,18 @@ class AsyncAuth(object):
|
|||||||
loop_instance_map = AsyncAuth.instance_map[io_loop]
|
loop_instance_map = AsyncAuth.instance_map[io_loop]
|
||||||
|
|
||||||
key = cls.__key(opts)
|
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))
|
log.debug('Initializing new AsyncAuth for {0}'.format(key))
|
||||||
# we need to make a local variable for this, as we are going to store
|
# 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
|
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||||
# references it-- this forces a reference while we return to the caller
|
# references it-- this forces a reference while we return to the caller
|
||||||
new_auth = object.__new__(cls)
|
auth = object.__new__(cls)
|
||||||
new_auth.__singleton_init__(opts, io_loop=io_loop)
|
auth.__singleton_init__(opts, io_loop=io_loop)
|
||||||
loop_instance_map[key] = new_auth
|
loop_instance_map[key] = auth
|
||||||
else:
|
else:
|
||||||
log.debug('Re-using AsyncAuth for {0}'.format(key))
|
log.debug('Re-using AsyncAuth for {0}'.format(key))
|
||||||
return loop_instance_map[key]
|
return auth
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __key(cls, opts, io_loop=None):
|
def __key(cls, opts, io_loop=None):
|
||||||
@ -1009,14 +1010,15 @@ class SAuth(AsyncAuth):
|
|||||||
Only create one instance of SAuth per __key()
|
Only create one instance of SAuth per __key()
|
||||||
'''
|
'''
|
||||||
key = cls.__key(opts)
|
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))
|
log.debug('Initializing new SAuth for {0}'.format(key))
|
||||||
new_auth = object.__new__(cls)
|
auth = object.__new__(cls)
|
||||||
new_auth.__singleton_init__(opts)
|
auth.__singleton_init__(opts)
|
||||||
SAuth.instances[key] = new_auth
|
SAuth.instances[key] = auth
|
||||||
else:
|
else:
|
||||||
log.debug('Re-using SAuth for {0}'.format(key))
|
log.debug('Re-using SAuth for {0}'.format(key))
|
||||||
return SAuth.instances[key]
|
return auth
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __key(cls, opts, io_loop=None):
|
def __key(cls, opts, io_loop=None):
|
||||||
|
@ -710,18 +710,21 @@ def check_hash(path, file_hash):
|
|||||||
|
|
||||||
hash
|
hash
|
||||||
The hash to check against the file specified in the ``path`` argument.
|
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``),
|
accompanying hash type (e.g. ``e138491e9d5b97023cea823fe17bac22``),
|
||||||
but for earlier releases it is necessary to also specify the hash type
|
but for earlier releases it is necessary to also specify the hash type
|
||||||
in the format ``<hash_type>:<hash_value>`` (e.g.
|
in the format ``<hash_type>=<hash_value>`` (e.g.
|
||||||
``md5:e138491e9d5b97023cea823fe17bac22``).
|
``md5=e138491e9d5b97023cea823fe17bac22``).
|
||||||
|
|
||||||
CLI Example:
|
CLI Example:
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
salt '*' file.check_hash /etc/fstab e138491e9d5b97023cea823fe17bac22
|
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)
|
path = os.path.expanduser(path)
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ def align_check(device, part_type, partition):
|
|||||||
'Invalid partition passed to partition.align_check'
|
'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
|
device, part_type, partition
|
||||||
)
|
)
|
||||||
out = __salt__['cmd.run'](cmd).splitlines()
|
out = __salt__['cmd.run'](cmd).splitlines()
|
||||||
|
@ -135,6 +135,7 @@ def _safe_output(line):
|
|||||||
'''
|
'''
|
||||||
return not any([
|
return not any([
|
||||||
line.startswith('Listing') and line.endswith('...'),
|
line.startswith('Listing') and line.endswith('...'),
|
||||||
|
line.startswith('Listing') and '\t' not in line,
|
||||||
'...done' in line,
|
'...done' in line,
|
||||||
line.startswith('WARNING:')
|
line.startswith('WARNING:')
|
||||||
])
|
])
|
||||||
|
@ -875,12 +875,26 @@ def set_wu_settings(level=None,
|
|||||||
Change Windows Update settings. If no parameters are passed, the current
|
Change Windows Update settings. If no parameters are passed, the current
|
||||||
value will be returned.
|
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:
|
:param int level:
|
||||||
Number from 1 to 4 indicating the update level:
|
Number from 1 to 4 indicating the update level:
|
||||||
1. Never check for updates
|
1. Never check for updates
|
||||||
2. Check for updates but let me choose whether to download and install them
|
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
|
3. Download updates but let me choose whether to install them
|
||||||
4. Install updates automatically
|
4. Install updates automatically
|
||||||
|
|
||||||
:param bool recommended:
|
:param bool recommended:
|
||||||
Boolean value that indicates whether to include optional or recommended
|
Boolean value that indicates whether to include optional or recommended
|
||||||
updates when a search for updates and installation of updates is
|
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
|
salt '*' win_wua.set_wu_settings level=4 recommended=True featured=False
|
||||||
|
|
||||||
'''
|
'''
|
||||||
ret = {}
|
# The AutomaticUpdateSettings.Save() method used in this function does not
|
||||||
ret['Success'] = True
|
# 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
|
# Initialize the PyCom system
|
||||||
pythoncom.CoInitialize()
|
pythoncom.CoInitialize()
|
||||||
|
@ -250,15 +250,16 @@ class IPCClient(object):
|
|||||||
# FIXME
|
# FIXME
|
||||||
key = str(socket_path)
|
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))
|
log.debug('Initializing new IPCClient for path: {0}'.format(key))
|
||||||
new_client = object.__new__(cls)
|
client = object.__new__(cls)
|
||||||
# FIXME
|
# FIXME
|
||||||
new_client.__singleton_init__(io_loop=io_loop, socket_path=socket_path)
|
client.__singleton_init__(io_loop=io_loop, socket_path=socket_path)
|
||||||
loop_instance_map[key] = new_client
|
loop_instance_map[key] = client
|
||||||
else:
|
else:
|
||||||
log.debug('Re-using IPCClient for {0}'.format(key))
|
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):
|
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]
|
loop_instance_map = cls.instance_map[io_loop]
|
||||||
|
|
||||||
key = cls.__key(opts, **kwargs)
|
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))
|
log.debug('Initializing new AsyncTCPReqChannel for {0}'.format(key))
|
||||||
# we need to make a local variable for this, as we are going to store
|
# 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
|
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||||
# references it-- this forces a reference while we return to the caller
|
# references it-- this forces a reference while we return to the caller
|
||||||
new_obj = object.__new__(cls)
|
obj = object.__new__(cls)
|
||||||
new_obj.__singleton_init__(opts, **kwargs)
|
obj.__singleton_init__(opts, **kwargs)
|
||||||
loop_instance_map[key] = new_obj
|
loop_instance_map[key] = obj
|
||||||
else:
|
else:
|
||||||
log.debug('Re-using AsyncTCPReqChannel for {0}'.format(key))
|
log.debug('Re-using AsyncTCPReqChannel for {0}'.format(key))
|
||||||
return loop_instance_map[key]
|
return obj
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def __key(cls, opts, **kwargs):
|
def __key(cls, opts, **kwargs):
|
||||||
|
@ -80,28 +80,19 @@ class AsyncZeroMQReqChannel(salt.transport.client.ReqChannel):
|
|||||||
loop_instance_map = cls.instance_map[io_loop]
|
loop_instance_map = cls.instance_map[io_loop]
|
||||||
|
|
||||||
key = cls.__key(opts, **kwargs)
|
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))
|
log.debug('Initializing new AsyncZeroMQReqChannel for {0}'.format(key))
|
||||||
# we need to make a local variable for this, as we are going to store
|
# 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
|
# it in a WeakValueDictionary-- which will remove the item if no one
|
||||||
# references it-- this forces a reference while we return to the caller
|
# references it-- this forces a reference while we return to the caller
|
||||||
new_obj = object.__new__(cls)
|
obj = object.__new__(cls)
|
||||||
new_obj.__singleton_init__(opts, **kwargs)
|
obj.__singleton_init__(opts, **kwargs)
|
||||||
loop_instance_map[key] = new_obj
|
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()))
|
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:
|
else:
|
||||||
log.debug('Re-using AsyncZeroMQReqChannel for {0}'.format(key))
|
log.debug('Re-using AsyncZeroMQReqChannel for {0}'.format(key))
|
||||||
try:
|
return obj
|
||||||
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]
|
|
||||||
|
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
|
Loading…
Reference in New Issue
Block a user