Add: scripts_all_pairs 'one way' mode

Add config parameter scripts_all_pairs_one_way
Add cli argument --one-way

Change-Id: I27237f2b8534a284b05aad63d9b78ca9ff9b943a
This commit is contained in:
Oleksandr Liemieshko 2016-12-15 19:25:33 -08:00
parent 6988c468d8
commit 4600fef101
6 changed files with 31 additions and 16 deletions

View File

@ -4,7 +4,7 @@
%global pypi_name timmy
Name: python-%{pypi_name}
Version: 1.25.5
Version: 1.26.0
Release: 1%{?dist}~mos0
Summary: Log collector tool for OpenStack Fuel
@ -107,6 +107,9 @@ popd
%changelog
* Thu Dec 15 2016 Alexander Lemeshko <oliemieshko@mirantis.com> - 1.26.0
- Add: scripts_all_pairs 'one way' mode
* Wed Dec 14 2016 Dmitry Sutyagin <dsutyagin@mirantis.com> - 1.25.5
- Fix: RuntimeWarning when using analyze

View File

@ -86,6 +86,11 @@ def parser_init(add_help=False):
' a path specified by "rqdir" configuration'
' parameter. For help on shell mode, read'
' timmy/conf.py.') % Node.skey)
parser.add_argument('--one-way', action='store_true',
help=('When executing scripts_all_pairs (if defined),'
' for each pair of nodes [A, B] run client'
' script only on A (A->B connection).'
' Default is to run both A->B and B->A.'))
parser.add_argument('-P', '--put', nargs=2, action='append',
metavar=('SOURCE', 'DESTINATION'),
help=('Enables shell mode. Can be specified multiple'
@ -300,6 +305,8 @@ def main(argv=None):
conf['analyze'] = True
if args.offline:
conf['offline'] = True
if args.one_way:
conf['scripts_all_pairs_one_way'] = True
logger.info('Using rqdir: %s, rqfile: %s' %
(conf['rqdir'], conf['rqfile']))
nm = pretty_run(args.quiet, 'Initializing node data',

View File

@ -74,6 +74,7 @@ def init_default_conf():
conf['clean'] = True
conf['analyze'] = False
conf['offline'] = False # mark all nodes as offline
conf['scripts_all_pairs_one_way'] = False
return conf

View File

@ -16,7 +16,7 @@
# under the License.
project_name = 'timmy'
version = '1.25.5'
version = '1.26.0'
if __name__ == '__main__':
import sys

View File

@ -902,13 +902,14 @@ class NodeManager(object):
@run_with_lock
def run_scripts_all_pairs(self, maxthreads, fake=False):
if len(self.selected_nodes) < 2:
nodes = self.selected_nodes.values()
if len(nodes) < 2:
self.logger.warning('less than 2 nodes are available, '
'skipping paired scripts')
return
run_server_start_items = []
run_server_stop_items = []
for n in self.selected_nodes.values():
for n in nodes:
start_args = {'phase': 'server_start', 'fake': fake}
run_server_start_items.append(tools.RunItem(target=n.exec_pair,
args=start_args,
@ -920,7 +921,8 @@ class NodeManager(object):
dict_result=True)
for key in result:
self.nodes[key].scripts_all_pairs = result[key]
for pairset in tools.all_pairs(self.selected_nodes.values()):
one_way = self.conf['scripts_all_pairs_one_way']
for pairset in tools.all_pairs(nodes, one_way=one_way):
run_client_items = []
self.logger.info(['%s->%s' % (p[0].ip, p[1].ip) for p in pairset])
for pair in pairset:

View File

@ -408,29 +408,31 @@ def w_list(value):
return value if type(value) == list else [value]
def all_pairs(items):
def incomplete(i_set, p_dict):
for i, p_set in p_dict.items():
not_paired = i_set.difference(p_set).difference([i])
if not_paired:
return not_paired
def all_pairs(items, one_way=False):
def incomplete(items_set, paired_dict):
for paired_set in paired_dict.values():
if items_set.difference(paired_set):
return True
items_set = set(items)
pairs = []
paired = {}
for i in items_set:
paired[i] = set()
paired[i] = set([i])
while incomplete(items_set, paired):
busy = set()
current_pairs = []
for i in [i for i in items if items_set.difference(paired[i])]:
can_pair = incomplete(items_set.difference(busy), {i: paired[i]})
if i not in busy and can_pair:
pair_i = next(iter(can_pair))
for i in items_set:
if items_set.difference(paired[i]) and i not in busy:
can_pair = items_set.difference(busy).difference(paired[i])
if can_pair:
pair_i = can_pair.pop()
current_pairs.append([i, pair_i])
busy.add(i)
busy.add(pair_i)
paired[i].add(pair_i)
if one_way:
paired[pair_i].add(i)
pairs.append(current_pairs)
return pairs