Mini Shell
"""
Splay function calls across targeted minions
"""
import logging
import time
import salt.utils.stringutils
log = logging.getLogger(__name__)
_DEFAULT_SPLAYTIME = 300
_HASH_SIZE = 8192
_HASH_VAL = None
def __init__(opts):
global _HASH_VAL
_HASH_VAL = _get_hash()
def _get_hash():
"""
Jenkins One-At-A-Time Hash Function
More Info: http://en.wikipedia.org/wiki/Jenkins_hash_function#one-at-a-time
"""
# Using bitmask to emulate rollover behavior of C unsigned 32 bit int
bitmask = 0xFFFFFFFF
h = 0
for i in bytearray(salt.utils.stringutils.to_bytes(__grains__["id"])):
h = (h + i) & bitmask
h = (h + (h << 10)) & bitmask
h = (h ^ (h >> 6)) & bitmask
h = (h + (h << 3)) & bitmask
h = (h ^ (h >> 11)) & bitmask
h = (h + (h << 15)) & bitmask
return (h & (_HASH_SIZE - 1)) & bitmask
def _calc_splay(splaytime):
return int(splaytime * _HASH_VAL / float(_HASH_SIZE))
def execute(opts, data, func, args, kwargs):
"""
Splay a salt function call execution time across minions over
a number of seconds (default: 300)
.. note::
You *probably* want to use --async here and look up the job results later.
If you're dead set on getting the output from the CLI command, then make
sure to set the timeout (with the -t flag) to something greater than the
splaytime (max splaytime + time to execute job).
Otherwise, it's very likely that the cli will time out before the job returns.
CLI Example:
.. code-block:: bash
# With default splaytime
salt --async --module-executors='[splay, direct_call]' '*' pkg.install cowsay version=3.03-8.el6
.. code-block:: bash
# With specified splaytime (5 minutes) and timeout with 10 second buffer
salt -t 310 --module-executors='[splay, direct_call]' --executor-opts='{splaytime: 300}' '*' pkg.version cowsay
"""
if "executor_opts" in data and "splaytime" in data["executor_opts"]:
splaytime = data["executor_opts"]["splaytime"]
else:
splaytime = opts.get("splaytime", _DEFAULT_SPLAYTIME)
if splaytime <= 0:
raise ValueError("splaytime must be a positive integer")
fun_name = data.get("fun")
my_delay = _calc_splay(splaytime)
log.debug("Splay is sleeping %s secs on %s", my_delay, fun_name)
time.sleep(my_delay)
return None
Zerion Mini Shell 1.0