mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
bugfix: persist accumulator data after reload_modules, fix #8881
This commit is contained in:
parent
85e32d1811
commit
ca907b4b41
@ -565,6 +565,7 @@ class State(object):
|
||||
self.pre = {}
|
||||
self.__run_num = 0
|
||||
self.jid = jid
|
||||
self.instance_id = str(id(self))
|
||||
|
||||
def _gather_pillar(self):
|
||||
'''
|
||||
@ -1486,6 +1487,7 @@ class State(object):
|
||||
# state module to change these at runtime.
|
||||
'__low__': immutabletypes.freeze(low),
|
||||
'__running__': immutabletypes.freeze(running) if running else {},
|
||||
'__instance_id__': self.instance_id,
|
||||
'__lowstate__': immutabletypes.freeze(chunks) if chunks else {}
|
||||
}
|
||||
|
||||
@ -1999,6 +2001,21 @@ class State(object):
|
||||
return errors
|
||||
ret = self.call_chunks(chunks)
|
||||
ret = self.call_listen(chunks, ret)
|
||||
|
||||
def _cleanup_accumulator_data():
|
||||
accum_data_path = os.path.join(
|
||||
salt.utils.get_accumulator_dir(self.opts['cachedir']),
|
||||
self.instance_id
|
||||
)
|
||||
try:
|
||||
os.remove(accum_data_path)
|
||||
log.debug('Deleted accumulator data file %s',
|
||||
accum_data_path)
|
||||
except OSError:
|
||||
log.debug('File %s does not exist, no need to cleanup.',
|
||||
accum_data_path)
|
||||
_cleanup_accumulator_data()
|
||||
|
||||
return ret
|
||||
|
||||
def render_template(self, high, template):
|
||||
|
@ -244,6 +244,7 @@ import traceback
|
||||
import yaml
|
||||
|
||||
# Import salt libs
|
||||
import salt.payload
|
||||
import salt.utils
|
||||
import salt.utils.templates
|
||||
from salt.exceptions import CommandExecutionError
|
||||
@ -255,8 +256,39 @@ log = logging.getLogger(__name__)
|
||||
|
||||
COMMENT_REGEX = r'^([[:space:]]*){0}[[:space:]]?'
|
||||
|
||||
_ACCUMULATORS = {}
|
||||
_ACCUMULATORS_DEPS = {}
|
||||
|
||||
def _get_accumulator_filepath():
|
||||
'''
|
||||
Return accumulator data path.
|
||||
'''
|
||||
return os.path.join(salt.utils.get_accumulator_dir(__opts__['cachedir']),
|
||||
__instance_id__)
|
||||
|
||||
|
||||
def _load_accumulators():
|
||||
def _deserialize(path):
|
||||
serial = salt.payload.Serial(__opts__)
|
||||
ret = {'accumulators': {}, 'accumulators_deps': {}}
|
||||
try:
|
||||
with open(path, 'rb') as f:
|
||||
loaded = serial.load(f)
|
||||
return loaded if loaded else ret
|
||||
except IOError:
|
||||
return ret
|
||||
|
||||
loaded = _deserialize(_get_accumulator_filepath())
|
||||
|
||||
return loaded['accumulators'], loaded['accumulators_deps']
|
||||
|
||||
|
||||
def _persist_accummulators(accumulators, accumulators_deps):
|
||||
|
||||
accumm_data = {'accumulators': accumulators,
|
||||
'accumulators_deps': accumulators_deps}
|
||||
|
||||
serial = salt.payload.Serial(__opts__)
|
||||
with open(_get_accumulator_filepath(), 'w+b') as f:
|
||||
serial.dump(accumm_data, f)
|
||||
|
||||
|
||||
def _check_user(user, group):
|
||||
@ -1300,10 +1332,11 @@ def managed(name,
|
||||
'No changes made.'.format(name))
|
||||
return ret
|
||||
|
||||
if name in _ACCUMULATORS:
|
||||
accum_data, _ = _load_accumulators()
|
||||
if name in accum_data:
|
||||
if not context:
|
||||
context = {}
|
||||
context['accumulator'] = _ACCUMULATORS[name]
|
||||
context['accumulator'] = accum_data[name]
|
||||
|
||||
try:
|
||||
if __opts__['test']:
|
||||
@ -2377,11 +2410,12 @@ def blockreplace(
|
||||
if not check_res:
|
||||
return _error(ret, check_msg)
|
||||
|
||||
if name in _ACCUMULATORS:
|
||||
accumulator = _ACCUMULATORS[name]
|
||||
accum_data, accum_deps = _load_accumulators()
|
||||
if name in accum_data:
|
||||
accumulator = accum_data[name]
|
||||
# if we have multiple accumulators for a file, only apply the one
|
||||
# required at a time
|
||||
deps = _ACCUMULATORS_DEPS.get(name, [])
|
||||
deps = accum_deps.get(name, [])
|
||||
filtered = [a for a in deps if
|
||||
__low__['__id__'] in deps[a] and a in accumulator]
|
||||
if not filtered:
|
||||
@ -3616,21 +3650,23 @@ def accumulated(name, filename, text, **kwargs):
|
||||
return ret
|
||||
if isinstance(text, string_types):
|
||||
text = (text,)
|
||||
if filename not in _ACCUMULATORS:
|
||||
_ACCUMULATORS[filename] = {}
|
||||
if filename not in _ACCUMULATORS_DEPS:
|
||||
_ACCUMULATORS_DEPS[filename] = {}
|
||||
if name not in _ACCUMULATORS_DEPS[filename]:
|
||||
_ACCUMULATORS_DEPS[filename][name] = []
|
||||
accum_data, accum_deps = _load_accumulators()
|
||||
if filename not in accum_data:
|
||||
accum_data[filename] = {}
|
||||
if filename not in accum_deps:
|
||||
accum_deps[filename] = {}
|
||||
if name not in accum_deps[filename]:
|
||||
accum_deps[filename][name] = []
|
||||
for accumulator in deps:
|
||||
_ACCUMULATORS_DEPS[filename][name].extend(accumulator.itervalues())
|
||||
if name not in _ACCUMULATORS[filename]:
|
||||
_ACCUMULATORS[filename][name] = []
|
||||
accum_deps[filename][name].extend(accumulator.itervalues())
|
||||
if name not in accum_data[filename]:
|
||||
accum_data[filename][name] = []
|
||||
for chunk in text:
|
||||
if chunk not in _ACCUMULATORS[filename][name]:
|
||||
_ACCUMULATORS[filename][name].append(chunk)
|
||||
if chunk not in accum_data[filename][name]:
|
||||
accum_data[filename][name].append(chunk)
|
||||
ret['comment'] = ('Accumulator {0} for file {1} '
|
||||
'was charged by text'.format(name, filename))
|
||||
_persist_accummulators(accum_data, accum_deps)
|
||||
return ret
|
||||
|
||||
|
||||
|
@ -574,6 +574,18 @@ def required_modules_error(name, docstring):
|
||||
return msg.format(filename, ', '.join(modules))
|
||||
|
||||
|
||||
def get_accumulator_dir(cachedir):
|
||||
'''
|
||||
Return the directory that accumulator data is stored in, creating it if it
|
||||
doesn't exist.
|
||||
'''
|
||||
fn_ = os.path.join(cachedir, 'accumulator')
|
||||
if not os.path.isdir(fn_):
|
||||
# accumulator_dir is not present, create it
|
||||
os.makedirs(fn_)
|
||||
return fn_
|
||||
|
||||
|
||||
def gen_jid():
|
||||
'''
|
||||
Generate a jid
|
||||
|
Loading…
Reference in New Issue
Block a user