Remove overstate system

Overstate has been on a deprecation path and is scheduled to be removed in Boron. This removes all overstate functionality in favour of orchestrate.
This commit is contained in:
Mike Place 2015-05-05 10:49:39 -06:00
parent 95dc331da8
commit c4a796120a
2 changed files with 1 additions and 395 deletions

View File

@ -1,323 +0,0 @@
# -*- coding: utf-8 -*-
'''
Manage the process of the overstate. The overstate is a means to orchestrate
the deployment of states over groups of servers.
*********************************************
WARNING: The overstate system is deprecated!
This functionality will be retired in the Boron
release of Salt.
Please migrate to state.orchestrate
**********************************************
'''
from __future__ import absolute_import
# 1. Read in overstate
# 2. Create initial order
# 3. Start list evaluation
# 4. Verify requisites
# 5. Execute state call
# 6. append data to running
# Import python libs
import os
# Import salt libs
import salt.client
import salt.utils
# Import third party libs
import yaml
import salt.ext.six as six
class OverState(object):
'''
Manage sls file calls over multiple systems
*********************************************
WARNING: The overstate system is deprecated!
This functionality will be retired in the Boron
release of Salt.
Please migrate to state.orchestrate
**********************************************
'''
def __init__(self, opts, saltenv='base', overstate=None, env=None):
if env is not None:
salt.utils.warn_until(
'Boron',
'Passing a salt environment should be done using \'saltenv\' '
'not \'env\'. This functionality will be removed in Salt '
'Boron.'
)
# Backwards compatibility
saltenv = env
self.opts = opts
self.saltenv = saltenv
self.over = self.__read_over(overstate)
self.names = self._names()
self.local = salt.client.get_local_client(self.opts['conf_file'])
self.over_run = {}
def __read_over(self, overstate):
'''
Read in the overstate file
'''
if overstate:
with salt.utils.fopen(overstate) as fp_:
try:
# TODO Use render system
return self.__sort_stages(yaml.safe_load(fp_))
except Exception:
return {}
if self.saltenv not in self.opts['file_roots']:
return {}
for root in self.opts['file_roots'][self.saltenv]:
fn_ = os.path.join(
root,
self.opts.get('overstate', 'overstate.sls')
)
if not os.path.isfile(fn_):
continue
with salt.utils.fopen(fn_) as fp_:
try:
# TODO Use render system
return self.__sort_stages(yaml.safe_load(fp_))
except Exception:
return {}
return {}
def __sort_stages(self, pre_over):
'''
Generate the list of executions
'''
comps = []
for key in sorted(pre_over):
comps.append({key: pre_over[key]})
return comps
def _stage_list(self, match):
'''
Return a list of ids cleared for a given stage
'''
if isinstance(match, list):
match = ' or '.join(match)
raw = self.local.cmd(match, 'test.ping', expr_form='compound')
return list(raw.keys())
def _names(self):
'''
Return a list of names defined in the overstate
'''
names = set()
for comp in self.over:
names.add(next(six.iterkeys(comp)))
return names
def get_stage(self, name):
'''
Return the named stage
'''
for stage in self.over:
if name in stage:
return stage
def _check_results(self, req, name, results, req_fail):
for minion in self.over_run[req]:
running = {minion: self.over_run[req][minion]['ret']}
if self.over_run[req][minion]['fun'] == 'state.highstate':
if salt.utils.check_state_result(running):
# This req is good, check the next
continue
elif self.over_run[req][minion]['fun'] == 'state.sls':
if salt.utils.check_state_result(running):
# This req is good, check the next
continue
else:
if not self.over_run[req][minion]['retcode']:
if self.over_run[req][minion]['success']:
continue
tag_name = 'req_|-fail_|-fail_|-None'
failure = {tag_name: {
'ret': {
'result': False,
'comment': 'Requisite {0} failed for stage on minion {1}'.format(req, minion),
'name': 'Requisite Failure',
'changes': {},
'__run_num__': 0,
},
'retcode': 254,
'success': False,
'fun': 'req.fail',
}
}
results[name] = failure
req_fail[name].update(failure)
return results, req_fail
def verify_stage(self, stage):
'''
Verify that the stage is valid, return the stage, or a list of errors
'''
errors = []
if 'match' not in stage:
errors.append('No "match" argument in stage.')
if errors:
return errors
return stage
def call_stage(self, name, stage):
'''
Check if a stage has any requisites and run them first
'''
fun = 'state.highstate'
arg = ()
req_fail = {name: {}}
if 'sls' in stage:
fun = 'state.sls'
arg = (','.join(stage['sls']), self.saltenv)
elif 'function' in stage or 'fun' in stage:
fun_d = stage.get('function', stage.get('fun'))
if not fun_d:
# Function dict is empty
yield {name: {}}
if isinstance(fun_d, str):
fun = fun_d
elif isinstance(fun_d, dict):
fun = next(six.iterkeys(fun_d))
arg = fun_d[fun]
else:
yield {name: {}}
reqs = stage.get('require') or []
for req in reqs:
if req in self.over_run:
# The req has been called, check it
self.over_run, req_fail = self._check_results(req,
name, self.over_run, req_fail)
elif req not in self.names:
# Req does not exist
tag_name = 'No_|-Req_|-fail_|-None'
failure = {tag_name: {
'ret': {
'result': False,
'comment': 'Requisite {0} not found'.format(req),
'name': 'Requisite Failure',
'changes': {},
'__run_num__': 0,
},
'retcode': 253,
'success': False,
'fun': 'req.fail',
}
}
self.over_run[name] = failure
req_fail[name].update(failure)
else:
# Req has not be called
for comp in self.over:
rname = next(six.iterkeys(comp))
if req == rname:
rstage = comp[rname]
v_stage = self.verify_stage(rstage)
if isinstance(v_stage, list):
yield {rname: v_stage}
else:
yield self.call_stage(rname, rstage)
# Verify that the previous yield returned
# successfully and update req_fail
self.over_run, req_fail = self._check_results(req,
name, self.over_run, req_fail)
# endfor
if req_fail[name]:
yield req_fail
else:
ret = {}
tgt = self._stage_list(stage['match'])
cmd_kwargs = {
'tgt': tgt,
'fun': fun,
'arg': arg,
'expr_form': 'list',
'raw': True}
if 'batch' in stage:
local_cmd = self.local.cmd_batch
cmd_kwargs['batch'] = stage['batch']
else:
local_cmd = self.local.cmd_iter
for minion in local_cmd(**cmd_kwargs):
if all(key not in minion for key in ('id', 'return', 'fun')):
continue
ret.update({minion['id']:
{
'ret': minion['return'],
'fun': minion['fun'],
'retcode': minion.get('retcode', 0),
'success': minion.get('success', True),
}
})
self.over_run[name] = ret
yield {name: ret}
def stages(self):
'''
Execute the stages
'''
self.over_run = {}
for comp in self.over:
name = next(six.iterkeys(comp))
stage = comp[name]
if name not in self.over_run:
self.call_stage(name, stage)
def stages_iter(self):
'''
Return an iterator that yields the state call data as it is processed
'''
def yielder(gen_ret):
if (not isinstance(gen_ret, list)
and not isinstance(gen_ret, dict)
and hasattr(gen_ret, 'next')):
for sub_ret in gen_ret:
for yret in yielder(sub_ret):
yield yret
else:
yield gen_ret
self.over_run = {}
yield self.over
for comp in self.over:
name = next(six.iterkeys(comp))
stage = comp[name]
if name not in self.over_run:
v_stage = self.verify_stage(stage)
if isinstance(v_stage, list):
yield [comp]
yield v_stage
else:
for sret in self.call_stage(name, stage):
for yret in yielder(sret):
sname = next(six.iterkeys(yret))
yield [self.get_stage(sname)]
final = {}
for minion in yret[sname]:
final[minion] = yret[sname][minion]['ret']
yield final

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
'''
Execute overstate functions
Execute orchestration functions
'''
# Import pytohn libs
from __future__ import absolute_import, print_function
@ -10,7 +10,6 @@ import logging
import sys
# Import salt libs
import salt.overstate
import salt.syspaths
import salt.utils.event
from salt.exceptions import SaltInvocationError
@ -21,59 +20,6 @@ import salt.ext.six as six
LOGGER = logging.getLogger(__name__)
def over(saltenv='base', os_fn=None):
'''
.. versionadded:: 0.11.0
.. warning::
``state.over`` is deprecated in favor of ``state.orchestrate``, and
will be removed in the Salt feature release codenamed Boron.
(Three feature releases after the 2014.7.0 release, which is codenamed
Helium)
Execute an overstate sequence to orchestrate the executing of states
over a group of systems
CLI Examples:
.. code-block:: bash
salt-run state.over base /path/to/myoverstate.sls
'''
salt.utils.warn_until(
'Boron',
'The state.over runner is on a deprecation path and will be '
'removed in Salt Boron. Please migrate to state.orchestrate.'
)
stage_num = 0
try:
overstate = salt.overstate.OverState(__opts__, saltenv, os_fn)
except IOError as exc:
raise SaltInvocationError(
'{0}: {1!r}'.format(exc.strerror, exc.filename)
)
for stage in overstate.stages_iter():
if isinstance(stage, dict):
# This is highstate data
__jid_event__.fire_event({'message': 'Stage execution results:'}, 'progress')
for key, val in six.iteritems(stage):
if '_|-' in key:
__jid_event__.fire_event({'data': {'error': {key: val}}, 'outputter': 'highstate'}, 'progress')
else:
__jid_event__.fire_event({'data': {key: val}, 'outputter': 'highstate'}, 'progress')
elif isinstance(stage, list):
# This is a stage
if stage_num == 0:
__jid_event__.fire_event({'message': 'Executing the following Over State:'}, 'progress')
else:
__jid_event__.fire_event({'message': 'Executed Stage:'}, 'progress')
__jid_event__.fire_event({'data': stage, 'outputter': 'overstatestage'}, 'progress')
stage_num += 1
return overstate.over_run
def orchestrate(mods, saltenv='base', test=None, exclude=None, pillar=None):
'''
.. versionadded:: 0.17.0
@ -187,23 +133,6 @@ def orchestrate_high(data, test=None, queue=False, pillar=None, **kwargs):
return ret
def show_stages(saltenv='base', os_fn=None):
'''
.. versionadded:: 0.11.0
Display the OverState's stage data
CLI Examples:
.. code-block:: bash
salt-run state.show_stages
salt-run state.show_stages saltenv=dev /root/overstate.sls
'''
overstate = salt.overstate.OverState(__opts__, saltenv, os_fn)
__jid_event__.fire_event({'data': overstate.over, 'outputter': 'overstatestage'}, 'progress')
return overstate.over
def event(tagmatch='*', count=-1, quiet=False, sock_dir=None, pretty=False):
r'''